1. Project Clover database Tue Apr 9 2024 12:11:48 CDT
  2. Package com.alibaba.fastjson.util

File TypeUtils.java

 
test_date: parseLong error, field : value
 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
23% of files have more coverage

Code metrics

1,072
1,679
95
1
3,145
2,794
833
0.5
17.67
95
8.77

Classes

Class Line # Actions
TypeUtils 60 1,679 0% 833 318
0.8882642488.8%
 

Contributing tests

This file is covered by 2601 tests. .

Source view

1    /*
2    * Copyright 1999-2017 Alibaba Group.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package com.alibaba.fastjson.util;
17   
18    import com.alibaba.fastjson.JSON;
19    import com.alibaba.fastjson.JSONException;
20    import com.alibaba.fastjson.JSONObject;
21    import com.alibaba.fastjson.PropertyNamingStrategy;
22    import com.alibaba.fastjson.annotation.JSONField;
23    import com.alibaba.fastjson.annotation.JSONType;
24    import com.alibaba.fastjson.parser.DefaultJSONParser;
25    import com.alibaba.fastjson.parser.Feature;
26    import com.alibaba.fastjson.parser.JSONScanner;
27    import com.alibaba.fastjson.parser.ParserConfig;
28    import com.alibaba.fastjson.parser.deserializer.EnumDeserializer;
29    import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
30    import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
31    import com.alibaba.fastjson.serializer.CalendarCodec;
32    import com.alibaba.fastjson.serializer.SerializeBeanInfo;
33    import com.alibaba.fastjson.serializer.SerializerFeature;
34   
35    import java.lang.annotation.Annotation;
36    import java.lang.reflect.AccessibleObject;
37    import java.lang.reflect.Array;
38    import java.lang.reflect.Constructor;
39    import java.lang.reflect.Field;
40    import java.lang.reflect.GenericArrayType;
41    import java.lang.reflect.Method;
42    import java.lang.reflect.Modifier;
43    import java.lang.reflect.ParameterizedType;
44    import java.lang.reflect.Proxy;
45    import java.lang.reflect.Type;
46    import java.lang.reflect.TypeVariable;
47    import java.lang.reflect.WildcardType;
48    import java.math.BigDecimal;
49    import java.math.BigInteger;
50    import java.security.AccessControlException;
51    import java.text.ParseException;
52    import java.text.SimpleDateFormat;
53    import java.util.*;
54    import java.util.concurrent.ConcurrentHashMap;
55    import java.util.concurrent.ConcurrentMap;
56   
57    /**
58    * @author wenshao[szujobs@hotmail.com]
59    */
 
60    public class TypeUtils{
61   
62    public static boolean compatibleWithJavaBean = false;
63    /** 根据field name的大小写输出输入数据 */
64    public static boolean compatibleWithFieldName = false;
65    private static boolean setAccessibleEnable = true;
66    private static boolean oracleTimestampMethodInited = false;
67    private static Method oracleTimestampMethod;
68    private static boolean oracleDateMethodInited = false;
69    private static Method oracleDateMethod;
70    private static boolean optionalClassInited = false;
71    private static Class<?> optionalClass;
72    private static boolean transientClassInited = false;
73    private static Class<? extends Annotation> transientClass;
74   
75    private static Class<? extends Annotation> class_OneToMany = null;
76    private static boolean class_OneToMany_error = false;
77    private static Class<? extends Annotation> class_ManyToMany = null;
78    private static boolean class_ManyToMany_error = false;
79   
80    private static Method method_HibernateIsInitialized = null;
81    private static boolean method_HibernateIsInitialized_error = false;
82    private static volatile Class kotlin_metadata;
83    private static volatile boolean kotlin_metadata_error;
84    private static volatile boolean kotlin_class_klass_error;
85    private static volatile Constructor kotlin_kclass_constructor;
86    private static volatile Method kotlin_kclass_getConstructors;
87    private static volatile Method kotlin_kfunction_getParameters;
88    private static volatile Method kotlin_kparameter_getName;
89    private static volatile boolean kotlin_error;
90    private static volatile Map<Class,String[]> kotlinIgnores;
91    private static volatile boolean kotlinIgnores_error;
92    private static ConcurrentMap<String,Class<?>> mappings = new ConcurrentHashMap<String,Class<?>>(256, 0.75f, 1);
93    private static Class<?> pathClass;
94    private static boolean pathClass_error = false;
95   
96    private static Class<? extends Annotation> class_JacksonCreator = null;
97    private static boolean class_JacksonCreator_error = false;
98   
99    private static volatile Class class_Clob = null;
100    private static volatile boolean class_Clob_error = false;
101   
102    private static volatile Class class_XmlAccessType = null;
103    private static volatile Class class_XmlAccessorType = null;
104    private static volatile boolean classXmlAccessorType_error = false;
105    private static volatile Method method_XmlAccessorType_value = null;
106    private static volatile Field field_XmlAccessType_FIELD = null;
107    private static volatile Object field_XmlAccessType_FIELD_VALUE = null;
108   
 
109  1 toggle static{
110  1 try{
111  1 TypeUtils.compatibleWithJavaBean = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHJAVABEAN));
112  1 TypeUtils.compatibleWithFieldName = "true".equals(IOUtils.getStringProperty(IOUtils.FASTJSON_COMPATIBLEWITHFIELDNAME));
113    } catch(Throwable e){
114    // skip
115    }
116    }
117   
 
118  1 toggle static{
119  1 addBaseClassMappings();
120    }
121   
122   
 
123  1194 toggle public static boolean isXmlField(Class clazz) {
124  1194 if (class_XmlAccessorType == null && !classXmlAccessorType_error) {
125  1 try {
126  1 class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType");
127    } catch(Throwable ex){
128  0 classXmlAccessorType_error = true;
129    }
130    }
131   
132  1194 if (class_XmlAccessorType == null) {
133  0 return false;
134    }
135   
136  1194 Annotation annotation = TypeUtils.getAnnotation(clazz, class_XmlAccessorType);
137  1194 if (annotation == null) {
138  1191 return false;
139    }
140   
141  3 if (method_XmlAccessorType_value == null && !classXmlAccessorType_error) {
142  1 try {
143  1 method_XmlAccessorType_value = class_XmlAccessorType.getMethod("value");
144    } catch(Throwable ex){
145  0 classXmlAccessorType_error = true;
146    }
147    }
148   
149  3 if (method_XmlAccessorType_value == null) {
150  0 return false;
151    }
152   
153  3 Object value = null;
154  3 if (!classXmlAccessorType_error) {
155  3 try {
156  3 value = method_XmlAccessorType_value.invoke(annotation);
157    } catch (Throwable ex) {
158  0 classXmlAccessorType_error = true;
159    }
160    }
161  3 if (value == null) {
162  0 return false;
163    }
164   
165  3 if (class_XmlAccessType == null && !classXmlAccessorType_error) {
166  1 try {
167  1 class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType");
168  1 field_XmlAccessType_FIELD = class_XmlAccessType.getField("FIELD");
169  1 field_XmlAccessType_FIELD_VALUE = field_XmlAccessType_FIELD.get(null);
170    } catch(Throwable ex){
171  0 classXmlAccessorType_error = true;
172    }
173    }
174   
175  3 return value == field_XmlAccessType_FIELD_VALUE;
176    }
177   
 
178  0 toggle public static Annotation getXmlAccessorType(Class clazz) {
179  0 if (class_XmlAccessorType == null && !classXmlAccessorType_error) {
180   
181  0 try{
182  0 class_XmlAccessorType = Class.forName("javax.xml.bind.annotation.XmlAccessorType");
183    } catch(Throwable ex){
184  0 classXmlAccessorType_error = true;
185    }
186    }
187   
188  0 if (class_XmlAccessorType == null) {
189  0 return null;
190    }
191   
192  0 return TypeUtils.getAnnotation(clazz, class_XmlAccessorType);
193    }
194   
195    //
196    // public static boolean isXmlAccessType(Class clazz) {
197    // if (class_XmlAccessType == null && !class_XmlAccessType_error) {
198    //
199    // try{
200    // class_XmlAccessType = Class.forName("javax.xml.bind.annotation.XmlAccessType");
201    // } catch(Throwable ex){
202    // class_XmlAccessType_error = true;
203    // }
204    // }
205    //
206    // if (class_XmlAccessType == null) {
207    // return false;
208    // }
209    //
210    // return class_XmlAccessType.isAssignableFrom(clazz);
211    // }
212   
 
213  1502 toggle public static boolean isClob(Class clazz) {
214  1502 if (class_Clob == null && !class_Clob_error) {
215   
216  1 try{
217  1 class_Clob = Class.forName("java.sql.Clob");
218    } catch(Throwable ex){
219  0 class_Clob_error = true;
220    }
221    }
222   
223  1502 if (class_Clob == null) {
224  0 return false;
225    }
226   
227  1502 return class_Clob.isAssignableFrom(clazz);
228    }
229   
 
230  57 toggle public static String castToString(Object value){
231  57 if(value == null){
232  2 return null;
233    }
234  55 return value.toString();
235    }
236   
 
237  30 toggle public static Byte castToByte(Object value){
238  30 if(value == null){
239  4 return null;
240    }
241   
242  26 if(value instanceof BigDecimal){
243  0 return byteValue((BigDecimal) value);
244    }
245   
246  26 if(value instanceof Number){
247  13 return ((Number) value).byteValue();
248    }
249   
250  13 if(value instanceof String){
251  10 String strVal = (String) value;
252  10 if(strVal.length() == 0 //
253    || "null".equals(strVal) //
254    || "NULL".equals(strVal)){
255  4 return null;
256    }
257  6 return Byte.parseByte(strVal);
258    }
259  3 throw new JSONException("can not cast to byte, value : " + value);
260    }
261   
 
262  19 toggle public static Character castToChar(Object value){
263  19 if(value == null){
264  1 return null;
265    }
266  18 if(value instanceof Character){
267  1 return (Character) value;
268    }
269  17 if(value instanceof String){
270  16 String strVal = (String) value;
271  16 if(strVal.length() == 0){
272  2 return null;
273    }
274  14 if(strVal.length() != 1){
275  1 throw new JSONException("can not cast to char, value : " + value);
276    }
277  13 return strVal.charAt(0);
278    }
279  1 throw new JSONException("can not cast to char, value : " + value);
280    }
281   
 
282  155 toggle public static Short castToShort(Object value){
283  155 if(value == null){
284  4 return null;
285    }
286   
287  151 if(value instanceof BigDecimal){
288  0 return shortValue((BigDecimal) value);
289    }
290   
291  151 if(value instanceof Number){
292  138 return ((Number) value).shortValue();
293    }
294   
295  13 if(value instanceof String){
296  10 String strVal = (String) value;
297  10 if(strVal.length() == 0 //
298    || "null".equals(strVal) //
299    || "NULL".equals(strVal)){
300  4 return null;
301    }
302  6 return Short.parseShort(strVal);
303    }
304   
305  3 throw new JSONException("can not cast to short, value : " + value);
306    }
307   
 
308  22 toggle public static BigDecimal castToBigDecimal(Object value){
309  22 if(value == null){
310  2 return null;
311    }
312  20 if(value instanceof BigDecimal){
313  1 return (BigDecimal) value;
314    }
315  19 if(value instanceof BigInteger){
316  1 return new BigDecimal((BigInteger) value);
317    }
318  18 String strVal = value.toString();
319  18 if(strVal.length() == 0){
320  1 return null;
321    }
322  17 if(value instanceof Map && ((Map) value).size() == 0){
323  1 return null;
324    }
325  16 return new BigDecimal(strVal);
326    }
327   
 
328  18 toggle public static BigInteger castToBigInteger(Object value){
329  18 if(value == null){
330  2 return null;
331    }
332  16 if(value instanceof BigInteger){
333  1 return (BigInteger) value;
334    }
335  15 if(value instanceof Float || value instanceof Double){
336  6 return BigInteger.valueOf(((Number) value).longValue());
337    }
338  9 if(value instanceof BigDecimal){
339  0 BigDecimal decimal = (BigDecimal) value;
340  0 int scale = decimal.scale();
341  0 if (scale > -1000 && scale < 1000) {
342  0 return ((BigDecimal) value).toBigInteger();
343    }
344    }
345  9 String strVal = value.toString();
346  9 if(strVal.length() == 0 //
347    || "null".equals(strVal) //
348    || "NULL".equals(strVal)){
349  2 return null;
350    }
351  7 return new BigInteger(strVal);
352    }
353   
 
354  12000162 toggle public static Float castToFloat(Object value){
355  12000162 if(value == null){
356  4 return null;
357    }
358  12000158 if(value instanceof Number){
359  12000144 return ((Number) value).floatValue();
360    }
361  14 if(value instanceof String){
362  11 String strVal = value.toString();
363  11 if(strVal.length() == 0 //
364    || "null".equals(strVal) //
365    || "NULL".equals(strVal)){
366  5 return null;
367    }
368  6 if(strVal.indexOf(',') != 0){
369  6 strVal = strVal.replaceAll(",", "");
370    }
371  6 return Float.parseFloat(strVal);
372    }
373  3 throw new JSONException("can not cast to float, value : " + value);
374    }
375   
 
376  2000167 toggle public static Double castToDouble(Object value){
377  2000167 if(value == null){
378  5 return null;
379    }
380  2000162 if(value instanceof Number){
381  2000147 return ((Number) value).doubleValue();
382    }
383  15 if(value instanceof String){
384  12 String strVal = value.toString();
385  12 if(strVal.length() == 0 //
386    || "null".equals(strVal) //
387    || "NULL".equals(strVal)){
388  6 return null;
389    }
390  6 if(strVal.indexOf(',') != 0){
391  6 strVal = strVal.replaceAll(",", "");
392    }
393  6 return Double.parseDouble(strVal);
394    }
395  3 throw new JSONException("can not cast to double, value : " + value);
396    }
397   
 
398  2040 toggle public static Date castToDate(Object value){
399  2040 Test failure here return castToDate(value, null);
400    }
401   
 
402  2044 toggle public static Date castToDate(Object value, String format){
403  2044 if(value == null){
404  2 return null;
405    }
406   
407  2042 if(value instanceof Date){ // 使用频率最高的,应优先处理
408  4 return (Date) value;
409    }
410   
411  2038 if(value instanceof Calendar){
412  1 return ((Calendar) value).getTime();
413    }
414   
415  2037 long longValue = -1;
416   
417  2037 if(value instanceof BigDecimal){
418  0 longValue = longValue((BigDecimal) value);
419  0 return new Date(longValue);
420    }
421   
422  2037 if(value instanceof Number){
423  2011 longValue = ((Number) value).longValue();
424  2011 if ("unixtime".equals(format)) {
425  2 longValue *= 1000;
426    }
427  2011 return new Date(longValue);
428    }
429   
430  26 if(value instanceof String){
431  23 String strVal = (String) value;
432  23 JSONScanner dateLexer = new JSONScanner(strVal);
433  23 try{
434  23 if(dateLexer.scanISO8601DateIfMatch(false)){
435  10 Calendar calendar = dateLexer.getCalendar();
436  10 return calendar.getTime();
437    }
438    } finally{
439  23 dateLexer.close();
440    }
441   
442  13 if (strVal.startsWith("/Date(") && strVal.endsWith(")/")) {
443  1 strVal = strVal.substring(6, strVal.length() - 2);
444    }
445   
446  13 if (strVal.indexOf('-') > 0 || strVal.indexOf('+') > 0) {
447  6 if (format == null) {
448  3 if (strVal.length() == JSON.DEFFAULT_DATE_FORMAT.length()
449    || (strVal.length() == 22 && JSON.DEFFAULT_DATE_FORMAT.equals("yyyyMMddHHmmssSSSZ"))) {
450  0 format = JSON.DEFFAULT_DATE_FORMAT;
451  3 } else if (strVal.length() == 10) {
452  1 format = "yyyy-MM-dd";
453  1 } else if (strVal.length() == "yyyy-MM-dd HH:mm:ss".length()) {
454  0 format = "yyyy-MM-dd HH:mm:ss";
455  1 } else if (strVal.length() == 29
456    && strVal.charAt(26) == ':'
457    && strVal.charAt(28) == '0') {
458  0 format = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
459  1 } else if (strVal.length() == 23 && strVal.charAt(19) == ',') {
460  1 format = "yyyy-MM-dd HH:mm:ss,SSS";
461    } else {
462  0 format = "yyyy-MM-dd HH:mm:ss.SSS";
463    }
464    }
465   
466  6 Test failure here SimpleDateFormat dateFormat = new SimpleDateFormat(format, JSON.defaultLocale);
467  5 dateFormat.setTimeZone(JSON.defaultTimeZone);
468  5 try{
469  5 return dateFormat.parse(strVal);
470    } catch(ParseException e){
471  1 throw new JSONException("can not cast to Date, value : " + strVal);
472    }
473    }
474  7 if(strVal.length() == 0){
475  2 return null;
476    }
477  5 longValue = Long.parseLong(strVal);
478    }
479   
480  7 if (longValue == -1) {
481  3 Class<?> clazz = value.getClass();
482  3 if("oracle.sql.TIMESTAMP".equals(clazz.getName())){
483  1 if(oracleTimestampMethod == null && !oracleTimestampMethodInited){
484  1 try{
485  1 oracleTimestampMethod = clazz.getMethod("toJdbc");
486    } catch(NoSuchMethodException e){
487    // skip
488    } finally{
489  1 oracleTimestampMethodInited = true;
490    }
491    }
492  1 Object result;
493  1 try{
494  1 result = oracleTimestampMethod.invoke(value);
495    } catch(Exception e){
496  0 throw new JSONException("can not cast oracle.sql.TIMESTAMP to Date", e);
497    }
498  1 return (Date) result;
499    }
500  2 if("oracle.sql.DATE".equals(clazz.getName())){
501  1 if(oracleDateMethod == null && !oracleDateMethodInited){
502  1 try{
503  1 oracleDateMethod = clazz.getMethod("toJdbc");
504    } catch(NoSuchMethodException e){
505    // skip
506    } finally{
507  1 oracleDateMethodInited = true;
508    }
509    }
510  1 Object result;
511  1 try{
512  1 result = oracleDateMethod.invoke(value);
513    } catch(Exception e){
514  0 throw new JSONException("can not cast oracle.sql.DATE to Date", e);
515    }
516  1 return (Date) result;
517    }
518   
519  1 throw new JSONException("can not cast to Date, value : " + value);
520    }
521   
522  4 return new Date(longValue);
523    }
524   
 
525  12 toggle public static java.sql.Date castToSqlDate(Object value){
526  12 if(value == null){
527  2 return null;
528    }
529  10 if(value instanceof java.sql.Date){
530  1 return (java.sql.Date) value;
531    }
532  9 if(value instanceof java.util.Date){
533  1 return new java.sql.Date(((java.util.Date) value).getTime());
534    }
535  8 if(value instanceof Calendar){
536  1 return new java.sql.Date(((Calendar) value).getTimeInMillis());
537    }
538   
539  7 long longValue = 0;
540  7 if(value instanceof BigDecimal){
541  0 longValue = longValue((BigDecimal) value);
542  7 } else if(value instanceof Number){
543  5 longValue = ((Number) value).longValue();
544    }
545   
546  7 if(value instanceof String){
547  2 String strVal = (String) value;
548  2 if(strVal.length() == 0 //
549    || "null".equals(strVal) //
550    || "NULL".equals(strVal)){
551  1 return null;
552    }
553  1 if(isNumber(strVal)){
554  1 longValue = Long.parseLong(strVal);
555    } else{
556  0 JSONScanner scanner = new JSONScanner(strVal);
557  0 if(scanner.scanISO8601DateIfMatch(false)){
558  0 longValue = scanner.getCalendar().getTime().getTime();
559    } else{
560  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
561    }
562    }
563    }
564  6 if(longValue <= 0){
565  1 throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理?
566    }
567  5 return new java.sql.Date(longValue);
568    }
569   
 
570  147 toggle public static long longExtractValue(Number number) {
571  147 if (number instanceof BigDecimal) {
572  11 return ((BigDecimal) number).longValueExact();
573    }
574   
575  136 return number.longValue();
576    }
577   
 
578  2 toggle public static java.sql.Time castToSqlTime(Object value){
579  2 if(value == null){
580  0 return null;
581    }
582  2 if(value instanceof java.sql.Time){
583  0 return (java.sql.Time) value;
584    }
585  2 if(value instanceof java.util.Date){
586  0 return new java.sql.Time(((java.util.Date) value).getTime());
587    }
588  2 if(value instanceof Calendar){
589  0 return new java.sql.Time(((Calendar) value).getTimeInMillis());
590    }
591   
592  2 long longValue = 0;
593  2 if(value instanceof BigDecimal){
594  0 longValue = longValue((BigDecimal) value);
595  2 } else if(value instanceof Number){
596  2 longValue = ((Number) value).longValue();
597    }
598   
599  2 if(value instanceof String){
600  0 String strVal = (String) value;
601  0 if(strVal.length() == 0 //
602    || "null".equalsIgnoreCase(strVal)){
603  0 return null;
604    }
605  0 if(isNumber(strVal)){
606  0 longValue = Long.parseLong(strVal);
607    } else{
608  0 JSONScanner scanner = new JSONScanner(strVal);
609  0 if(scanner.scanISO8601DateIfMatch(false)){
610  0 longValue = scanner.getCalendar().getTime().getTime();
611    } else{
612  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
613    }
614    }
615    }
616  2 if(longValue <= 0){
617  0 throw new JSONException("can not cast to Date, value : " + value); // TODO 忽略 1970-01-01 之前的时间处理?
618    }
619  2 return new java.sql.Time(longValue);
620    }
621   
 
622  21 toggle public static java.sql.Timestamp castToTimestamp(Object value){
623  21 if(value == null){
624  2 return null;
625    }
626  19 if(value instanceof Calendar){
627  1 return new java.sql.Timestamp(((Calendar) value).getTimeInMillis());
628    }
629  18 if(value instanceof java.sql.Timestamp){
630  1 return (java.sql.Timestamp) value;
631    }
632  17 if(value instanceof java.util.Date){
633  2 return new java.sql.Timestamp(((java.util.Date) value).getTime());
634    }
635  15 long longValue = 0;
636  15 if(value instanceof BigDecimal){
637  1 longValue = longValue((BigDecimal) value);
638  14 } else if(value instanceof Number){
639  7 longValue = ((Number) value).longValue();
640    }
641  15 if(value instanceof String){
642  7 String strVal = (String) value;
643  7 if(strVal.length() == 0 //
644    || "null".equals(strVal) //
645    || "NULL".equals(strVal)){
646  1 return null;
647    }
648  5 if(strVal.endsWith(".000000000")){
649  0 strVal = strVal.substring(0, strVal.length() - 10);
650  4 } else if(strVal.endsWith(".000000")){
651  0 strVal = strVal.substring(0, strVal.length() - 7);
652    }
653  1 if(isNumber(strVal)){
654  1 longValue = Long.parseLong(strVal);
655    } else{
656  0 JSONScanner scanner = new JSONScanner(strVal);
657  0 if(scanner.scanISO8601DateIfMatch(false)){
658  0 longValue = scanner.getCalendar().getTime().getTime();
659    } else{
660  0 throw new JSONException("can not cast to Timestamp, value : " + strVal);
661    }
662    }
663    }
664  9 if(longValue <= 0){
665  1 throw new JSONException("can not cast to Timestamp, value : " + value);
666    }
667  8 return new java.sql.Timestamp(longValue);
668    }
669   
 
670  72 toggle public static boolean isNumber(String str){
671  210 for(int i = 0; i < str.length(); ++i){
672  149 char ch = str.charAt(i);
673  149 if(ch == '+' || ch == '-'){
674  3 if(i != 0){
675  0 return false;
676    }
677  141 } else if(ch < '0' || ch > '9'){
678  6 return false;
679    }
680    }
681  61 return true;
682    }
683   
 
684  4384 toggle public static Long castToLong(Object value){
685  4384 if(value == null){
686  25 return null;
687    }
688   
689  4359 if(value instanceof BigDecimal){
690  0 return longValue((BigDecimal) value);
691    }
692   
693  4359 if(value instanceof Number){
694  2253 return ((Number) value).longValue();
695    }
696   
697  2106 if(value instanceof String){
698  2099 String strVal = (String) value;
699  2099 if(strVal.length() == 0 //
700    || "null".equals(strVal) //
701    || "NULL".equals(strVal)){
702  14 return null;
703    }
704  2085 if(strVal.indexOf(',') != 0){
705  2085 strVal = strVal.replaceAll(",", "");
706    }
707  2085 try{
708  2085 return Long.parseLong(strVal);
709    } catch(NumberFormatException ex){
710    //
711    }
712  2 JSONScanner dateParser = new JSONScanner(strVal);
713  2 Calendar calendar = null;
714  2 if(dateParser.scanISO8601DateIfMatch(false)){
715  0 calendar = dateParser.getCalendar();
716    }
717  2 dateParser.close();
718  2 if(calendar != null){
719  0 return calendar.getTimeInMillis();
720    }
721    }
722   
723  9 if(value instanceof Map){
724  4 Map map = (Map) value;
725  4 if(map.size() == 2
726    && map.containsKey("andIncrement")
727    && map.containsKey("andDecrement")){
728  3 Iterator iter = map.values().iterator();
729  3 iter.next();
730  3 Object value2 = iter.next();
731  3 return castToLong(value2);
732    }
733    }
734   
735  6 Test failure here throw new JSONException("can not cast to long, value : " + value);
736    }
737   
 
738  6 toggle public static byte byteValue(BigDecimal decimal) {
739  6 if (decimal == null) {
740  0 return 0;
741    }
742   
743  6 int scale = decimal.scale();
744  6 if (scale >= -100 && scale <= 100) {
745  5 return decimal.byteValue();
746    }
747   
748  1 return decimal.byteValueExact();
749    }
750   
 
751  8 toggle public static short shortValue(BigDecimal decimal) {
752  8 if (decimal == null) {
753  0 return 0;
754    }
755   
756  8 int scale = decimal.scale();
757  8 if (scale >= -100 && scale <= 100) {
758  5 return decimal.shortValue();
759    }
760   
761  3 return decimal.shortValueExact();
762    }
763   
 
764  3993 toggle public static int intValue(BigDecimal decimal) {
765  3993 if (decimal == null) {
766  0 return 0;
767    }
768   
769  3993 int scale = decimal.scale();
770  3993 if (scale >= -100 && scale <= 100) {
771  3991 return decimal.intValue();
772    }
773   
774  2 return decimal.intValueExact();
775    }
776   
 
777  9 toggle public static long longValue(BigDecimal decimal) {
778  9 if (decimal == null) {
779  0 return 0;
780    }
781   
782  9 int scale = decimal.scale();
783  9 if (scale >= -100 && scale <= 100) {
784  7 return decimal.longValue();
785    }
786   
787  2 return decimal.longValueExact();
788    }
789   
 
790  313 toggle public static Integer castToInt(Object value){
791  313 if(value == null){
792  6 return null;
793    }
794   
795  307 if(value instanceof Integer){
796  262 return (Integer) value;
797    }
798   
799  45 if(value instanceof BigDecimal){
800  0 return intValue((BigDecimal) value);
801    }
802   
803  45 if(value instanceof Number){
804  10 return ((Number) value).intValue();
805    }
806   
807  35 if(value instanceof String){
808  28 String strVal = (String) value;
809  28 if(strVal.length() == 0 //
810    || "null".equals(strVal) //
811    || "NULL".equals(strVal)){
812  14 return null;
813    }
814  14 if(strVal.indexOf(',') != 0){
815  14 strVal = strVal.replaceAll(",", "");
816    }
817  14 return Integer.parseInt(strVal);
818    }
819   
820  7 if(value instanceof Boolean){
821  1 return ((Boolean) value).booleanValue() ? 1 : 0;
822    }
823  6 if(value instanceof Map){
824  4 Map map = (Map) value;
825  4 if(map.size() == 2
826    && map.containsKey("andIncrement")
827    && map.containsKey("andDecrement")){
828  3 Iterator iter = map.values().iterator();
829  3 iter.next();
830  3 Object value2 = iter.next();
831  3 return castToInt(value2);
832    }
833    }
834  3 throw new JSONException("can not cast to int, value : " + value);
835    }
836   
 
837  5 toggle public static byte[] castToBytes(Object value){
838  5 if(value instanceof byte[]){
839  1 return (byte[]) value;
840    }
841  4 if(value instanceof String){
842  3 return IOUtils.decodeBase64((String) value);
843    }
844  1 throw new JSONException("can not cast to int, value : " + value);
845    }
846   
 
847  185 toggle public static Boolean castToBoolean(Object value){
848  185 if(value == null){
849  2 return null;
850    }
851  183 if(value instanceof Boolean){
852  145 return (Boolean) value;
853    }
854   
855  38 if(value instanceof BigDecimal){
856  0 return intValue((BigDecimal) value) == 1;
857    }
858   
859  38 if(value instanceof Number){
860  6 return ((Number) value).intValue() == 1;
861    }
862   
863  32 if(value instanceof String){
864  29 String strVal = (String) value;
865  29 if(strVal.length() == 0 //
866    || "null".equals(strVal) //
867    || "NULL".equals(strVal)){
868  6 return null;
869    }
870  23 if("true".equalsIgnoreCase(strVal) //
871    || "1".equals(strVal)){
872  10 return Boolean.TRUE;
873    }
874  13 if("false".equalsIgnoreCase(strVal) //
875    || "0".equals(strVal)){
876  6 return Boolean.FALSE;
877    }
878  7 if("Y".equalsIgnoreCase(strVal) //
879    || "T".equals(strVal)){
880  3 return Boolean.TRUE;
881    }
882  4 if("F".equalsIgnoreCase(strVal) //
883    || "N".equals(strVal)){
884  2 return Boolean.FALSE;
885    }
886    }
887  5 throw new JSONException("can not cast to boolean, value : " + value);
888    }
889   
 
890  96 toggle public static <T> T castToJavaBean(Object obj, Class<T> clazz){
891  96 Test failure here return cast(obj, clazz, ParserConfig.getGlobalInstance());
892    }
893   
 
894  10068347 toggle @SuppressWarnings({"unchecked", "rawtypes"})
895    public static <T> T cast(Object obj, Class<T> clazz, ParserConfig config){
896  10068347 if(obj == null){
897  255 if(clazz == int.class){
898  1 return (T) Integer.valueOf(0);
899  254 } else if(clazz == long.class){
900  1 return (T) Long.valueOf(0);
901  253 } else if(clazz == short.class){
902  1 return (T) Short.valueOf((short) 0);
903  252 } else if(clazz == byte.class){
904  1 return (T) Byte.valueOf((byte) 0);
905  251 } else if(clazz == float.class){
906  1 return (T) Float.valueOf(0);
907  250 } else if(clazz == double.class){
908  1 return (T) Double.valueOf(0);
909  249 } else if(clazz == boolean.class){
910  1 return (T) Boolean.FALSE;
911    }
912  248 return null;
913    }
914   
915  10068092 if(clazz == null){
916  1 throw new IllegalArgumentException("clazz is null");
917    }
918   
919  10068091 if(clazz == obj.getClass()){
920  53348 return (T) obj;
921    }
922   
923  10014743 if(obj instanceof Map){
924  3638 if(clazz == Map.class){
925  2 return (T) obj;
926    }
927   
928  3636 Map map = (Map) obj;
929  3636 if(clazz == Object.class && !map.containsKey(JSON.DEFAULT_TYPE_KEY)){
930  3 return (T) obj;
931    }
932  3633 return castToJavaBean((Map<String,Object>) obj, clazz, config);
933    }
934   
935  10011105 if(clazz.isArray()){
936  4032 if(obj instanceof Collection){
937  4026 Collection collection = (Collection) obj;
938  4026 int index = 0;
939  4026 Object array = Array.newInstance(clazz.getComponentType(), collection.size());
940  4026 for(Object item : collection){
941  8048 Object value = cast(item, clazz.getComponentType(), config);
942  8048 Array.set(array, index, value);
943  8048 index++;
944    }
945  4026 return (T) array;
946    }
947  6 if(clazz == byte[].class){
948  1 return (T) castToBytes(obj);
949    }
950    }
951   
952  10007078 if(clazz.isAssignableFrom(obj.getClass())){
953  29 return (T) obj;
954    }
955   
956  10007049 if(clazz == boolean.class || clazz == Boolean.class){
957  136 return (T) castToBoolean(obj);
958    }
959   
960  10006913 if(clazz == byte.class || clazz == Byte.class){
961  9 return (T) castToByte(obj);
962    }
963   
964  10006904 if(clazz == char.class || clazz == Character.class){
965  3 return (T) castToChar(obj);
966    }
967   
968  10006901 if(clazz == short.class || clazz == Short.class){
969  134 return (T) castToShort(obj);
970    }
971   
972  10006767 if(clazz == int.class || clazz == Integer.class){
973  190 return (T) castToInt(obj);
974    }
975   
976  10006577 if(clazz == long.class || clazz == Long.class){
977  2209 return (T) castToLong(obj);
978    }
979   
980  10004368 if(clazz == float.class || clazz == Float.class){
981  10000142 return (T) castToFloat(obj);
982    }
983   
984  4226 if(clazz == double.class || clazz == Double.class){
985  136 return (T) castToDouble(obj);
986    }
987   
988  4090 if(clazz == String.class){
989  4 return (T) castToString(obj);
990    }
991   
992  4086 if(clazz == BigDecimal.class){
993  2 return (T) castToBigDecimal(obj);
994    }
995   
996  4084 if(clazz == BigInteger.class){
997  1 return (T) castToBigInteger(obj);
998    }
999   
1000  4083 if(clazz == Date.class){
1001  2004 Test failure here return (T) castToDate(obj);
1002    }
1003   
1004  2079 if(clazz == java.sql.Date.class){
1005  7 return (T) castToSqlDate(obj);
1006    }
1007   
1008  2072 if(clazz == java.sql.Time.class){
1009  2 return (T) castToSqlTime(obj);
1010    }
1011   
1012  2070 if(clazz == java.sql.Timestamp.class){
1013  16 return (T) castToTimestamp(obj);
1014    }
1015   
1016  2054 if(clazz.isEnum()){
1017  6 return castToEnum(obj, clazz, config);
1018    }
1019   
1020  2048 if(Calendar.class.isAssignableFrom(clazz)){
1021  11 Date date = castToDate(obj);
1022  11 Calendar calendar;
1023  11 if(clazz == Calendar.class){
1024  5 calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale);
1025    } else{
1026  6 try{
1027  6 calendar = (Calendar) clazz.newInstance();
1028    } catch(Exception e){
1029  1 throw new JSONException("can not cast to : " + clazz.getName(), e);
1030    }
1031    }
1032  10 calendar.setTime(date);
1033  10 return (T) calendar;
1034    }
1035   
1036  2037 String className = clazz.getName();
1037  2037 if(className.equals("javax.xml.datatype.XMLGregorianCalendar")){
1038  4 Date date = castToDate(obj);
1039  4 Calendar calendar = Calendar.getInstance(JSON.defaultTimeZone, JSON.defaultLocale);
1040  4 calendar.setTime(date);
1041  4 return (T) CalendarCodec.instance.createXMLGregorianCalendar(calendar);
1042    }
1043   
1044  2033 if(obj instanceof String){
1045  2030 String strVal = (String) obj;
1046  2030 if(strVal.length() == 0 //
1047    || "null".equals(strVal) //
1048    || "NULL".equals(strVal)){
1049  5 return null;
1050    }
1051   
1052  2025 if(clazz == java.util.Currency.class){
1053  2 return (T) java.util.Currency.getInstance(strVal);
1054    }
1055   
1056  2023 if(clazz == java.util.Locale.class){
1057  1 return (T) toLocale(strVal);
1058    }
1059   
1060  2022 if (className.startsWith("java.time.")) {
1061  1 String json = JSON.toJSONString(strVal);
1062  1 return JSON.parseObject(json, clazz);
1063    }
1064    }
1065   
1066  2024 final ObjectDeserializer objectDeserializer = config.get(clazz);
1067  2021 if (objectDeserializer != null) {
1068  2020 String str = JSON.toJSONString(obj);
1069  2020 return JSON.parseObject(str, clazz);
1070    }
1071  1 throw new JSONException("can not cast to : " + clazz.getName());
1072    }
1073   
 
1074  6 toggle public static Locale toLocale(String strVal){
1075  6 String[] items = strVal.split("_");
1076  6 if(items.length == 1){
1077  1 return new Locale(items[0]);
1078    }
1079  5 if(items.length == 2){
1080  4 return new Locale(items[0], items[1]);
1081    }
1082  1 return new Locale(items[0], items[1], items[2]);
1083    }
1084   
 
1085  10 toggle @SuppressWarnings({"unchecked", "rawtypes"})
1086    public static <T> T castToEnum(Object obj, Class<T> clazz, ParserConfig mapping){
1087  10 try{
1088  10 if(obj instanceof String){
1089  5 String name = (String) obj;
1090  5 if(name.length() == 0){
1091  2 return null;
1092    }
1093   
1094  3 if (mapping == null) {
1095  2 mapping = ParserConfig.getGlobalInstance();
1096    }
1097   
1098  3 ObjectDeserializer deserializer = mapping.getDeserializer(clazz);
1099  3 if (deserializer instanceof EnumDeserializer) {
1100  3 EnumDeserializer enumDeserializer = (EnumDeserializer) deserializer;
1101  3 return (T) enumDeserializer.getEnumByHashCode(TypeUtils.fnv1a_64(name));
1102    }
1103   
1104  0 return (T) Enum.valueOf((Class<? extends Enum>) clazz, name);
1105    }
1106   
1107  5 if(obj instanceof BigDecimal){
1108  0 int ordinal = intValue((BigDecimal) obj);
1109  0 Object[] values = clazz.getEnumConstants();
1110  0 if(ordinal < values.length){
1111  0 return (T) values[ordinal];
1112    }
1113    }
1114   
1115  5 if(obj instanceof Number){
1116  4 int ordinal = ((Number) obj).intValue();
1117  4 Object[] values = clazz.getEnumConstants();
1118  4 if(ordinal < values.length){
1119  2 return (T) values[ordinal];
1120    }
1121    }
1122    } catch(Exception ex){
1123  0 throw new JSONException("can not cast to : " + clazz.getName(), ex);
1124    }
1125  3 throw new JSONException("can not cast to : " + clazz.getName());
1126    }
1127   
 
1128  10125 toggle @SuppressWarnings("unchecked")
1129    public static <T> T cast(Object obj, Type type, ParserConfig mapping){
1130  10125 if(obj == null){
1131  1 return null;
1132    }
1133  10124 if(type instanceof Class){
1134  10093 return cast(obj, (Class<T>) type, mapping);
1135    }
1136  31 if(type instanceof ParameterizedType){
1137  26 return (T) cast(obj, (ParameterizedType) type, mapping);
1138    }
1139  5 if(obj instanceof String){
1140  5 String strVal = (String) obj;
1141  5 if(strVal.length() == 0 //
1142    || "null".equals(strVal) //
1143    || "NULL".equals(strVal)){
1144  3 return null;
1145    }
1146    }
1147  2 if(type instanceof TypeVariable){
1148  1 return (T) obj;
1149    }
1150  1 throw new JSONException("can not cast to : " + type);
1151    }
1152   
 
1153  35 toggle @SuppressWarnings({"rawtypes", "unchecked"})
1154    public static <T> T cast(Object obj, ParameterizedType type, ParserConfig mapping){
1155  35 Type rawTye = type.getRawType();
1156   
1157  35 if(rawTye == List.class || rawTye == ArrayList.class){
1158  11 Type itemType = type.getActualTypeArguments()[0];
1159  11 if(obj instanceof List){
1160  6 List listObj = (List) obj;
1161  6 List arrayList = new ArrayList(listObj.size());
1162   
1163  14 for (int i = 0; i < listObj.size(); i++) {
1164  8 Object item = listObj.get(i);
1165   
1166  8 Object itemValue;
1167  8 if (itemType instanceof Class) {
1168  8 if (item != null && item.getClass() == JSONObject.class) {
1169  4 itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
1170    } else {
1171  4 itemValue = cast(item, (Class<T>) itemType, mapping);
1172    }
1173    } else {
1174  0 itemValue = cast(item, itemType, mapping);
1175    }
1176   
1177  8 arrayList.add(itemValue);
1178    }
1179  6 return (T) arrayList;
1180    }
1181    }
1182   
1183  29 if(rawTye == Set.class || rawTye == HashSet.class //
1184    || rawTye == TreeSet.class //
1185    || rawTye == Collection.class //
1186    || rawTye == List.class //
1187    || rawTye == ArrayList.class){
1188  9 Type itemType = type.getActualTypeArguments()[0];
1189  9 if(obj instanceof Iterable){
1190  5 Collection collection;
1191  5 if(rawTye == Set.class || rawTye == HashSet.class){
1192  2 collection = new HashSet();
1193  3 } else if(rawTye == TreeSet.class){
1194  1 collection = new TreeSet();
1195    } else{
1196  2 collection = new ArrayList();
1197    }
1198  13 for(Iterator it = ((Iterable) obj).iterator(); it.hasNext(); ){
1199  8 Object item = it.next();
1200   
1201  8 Object itemValue;
1202  8 if (itemType instanceof Class) {
1203  8 if (item != null && item.getClass() == JSONObject.class) {
1204  1 itemValue = ((JSONObject) item).toJavaObject((Class<T>) itemType, mapping, 0);
1205    } else {
1206  7 itemValue = cast(item, (Class<T>) itemType, mapping);
1207    }
1208    } else {
1209  0 itemValue = cast(item, itemType, mapping);
1210    }
1211   
1212  8 collection.add(itemValue);
1213    }
1214  5 return (T) collection;
1215    }
1216    }
1217   
1218  24 if(rawTye == Map.class || rawTye == HashMap.class){
1219  4 Type keyType = type.getActualTypeArguments()[0];
1220  4 Type valueType = type.getActualTypeArguments()[1];
1221  4 if(obj instanceof Map){
1222  3 Map map = new HashMap();
1223  3 for(Map.Entry entry : ((Map<?,?>) obj).entrySet()){
1224  3 Object key = cast(entry.getKey(), keyType, mapping);
1225  3 Object value = cast(entry.getValue(), valueType, mapping);
1226  3 map.put(key, value);
1227    }
1228  3 return (T) map;
1229    }
1230    }
1231  21 if(obj instanceof String){
1232  5 String strVal = (String) obj;
1233  5 if(strVal.length() == 0){
1234  3 return null;
1235    }
1236    }
1237  18 if(type.getActualTypeArguments().length == 1){
1238  5 Type argType = type.getActualTypeArguments()[0];
1239  5 if(argType instanceof WildcardType){
1240  2 return (T) cast(obj, rawTye, mapping);
1241    }
1242    }
1243   
1244  16 if (rawTye == Map.Entry.class && obj instanceof Map && ((Map) obj).size() == 1) {
1245  10 Map.Entry entry = (Map.Entry) ((Map) obj).entrySet().iterator().next();
1246  10 return (T) entry;
1247    }
1248   
1249  6 if (rawTye instanceof Class) {
1250  6 if (mapping == null) {
1251  3 mapping = ParserConfig.global;
1252    }
1253  6 ObjectDeserializer deserializer = mapping.getDeserializer(rawTye);
1254  6 if (deserializer != null) {
1255  6 String str = JSON.toJSONString(obj);
1256  6 DefaultJSONParser parser = new DefaultJSONParser(str, mapping);
1257  6 return (T) deserializer.deserialze(parser, type, null);
1258    }
1259    }
1260   
1261  0 throw new JSONException("can not cast to : " + type);
1262    }
1263   
 
1264  3680 toggle @SuppressWarnings({"unchecked"})
1265    public static <T> T castToJavaBean(Map<String,Object> map, Class<T> clazz, ParserConfig config){
1266  3680 try{
1267  3680 if(clazz == StackTraceElement.class){
1268  4 String declaringClass = (String) map.get("className");
1269  4 String methodName = (String) map.get("methodName");
1270  4 String fileName = (String) map.get("fileName");
1271  4 int lineNumber;
1272    {
1273  4 Number value = (Number) map.get("lineNumber");
1274  4 if(value == null) {
1275  1 lineNumber = 0;
1276  3 } else if (value instanceof BigDecimal) {
1277  0 lineNumber = ((BigDecimal) value).intValueExact();
1278    } else{
1279  3 lineNumber = value.intValue();
1280    }
1281    }
1282  4 return (T) new StackTraceElement(declaringClass, methodName, fileName, lineNumber);
1283    }
1284   
1285    {
1286  3676 Object iClassObject = map.get(JSON.DEFAULT_TYPE_KEY);
1287  3676 if(iClassObject instanceof String){
1288  8 String className = (String) iClassObject;
1289  8 Class<?> loadClazz;
1290  8 if(config == null){
1291  3 config = ParserConfig.global;
1292    }
1293  8 loadClazz = config.checkAutoType(className, null);
1294  5 if(loadClazz == null){
1295  0 throw new ClassNotFoundException(className + " not found");
1296    }
1297  5 if(!loadClazz.equals(clazz)){
1298  3 return (T) castToJavaBean(map, loadClazz, config);
1299    }
1300    }
1301    }
1302   
1303  3670 if(clazz.isInterface()){
1304  8 JSONObject object;
1305  8 if(map instanceof JSONObject){
1306  5 object = (JSONObject) map;
1307    } else{
1308  3 object = new JSONObject(map);
1309    }
1310  8 if(config == null){
1311  1 config = ParserConfig.getGlobalInstance();
1312    }
1313  8 ObjectDeserializer deserializer = config.get(clazz);
1314  8 if(deserializer != null){
1315  4 String json = JSON.toJSONString(object);
1316  4 return JSON.parseObject(json, clazz);
1317    }
1318  4 return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
1319    new Class<?>[]{clazz}, object);
1320    }
1321   
1322  3662 if(clazz == Locale.class){
1323  1 Object arg0 = map.get("language");
1324  1 Object arg1 = map.get("country");
1325  1 if(arg0 instanceof String){
1326  1 String language = (String) arg0;
1327  1 if(arg1 instanceof String){
1328  1 String country = (String) arg1;
1329  1 return (T) new Locale(language, country);
1330  0 } else if(arg1 == null){
1331  0 return (T) new Locale(language);
1332    }
1333    }
1334    }
1335   
1336  3661 if (clazz == String.class && map instanceof JSONObject) {
1337  1 return (T) map.toString();
1338    }
1339   
1340  3660 if (clazz == JSON.class && map instanceof JSONObject) {
1341  1 return (T) map;
1342    }
1343   
1344  3659 if (clazz == LinkedHashMap.class && map instanceof JSONObject) {
1345  1 JSONObject jsonObject = (JSONObject) map;
1346  1 Map innerMap = jsonObject.getInnerMap();
1347  1 if (innerMap instanceof LinkedHashMap) {
1348  1 return (T) innerMap;
1349    } else {
1350  0 LinkedHashMap linkedHashMap = new LinkedHashMap();
1351  0 linkedHashMap.putAll(innerMap);
1352    }
1353    }
1354   
1355  3658 if (clazz.isInstance(map)) {
1356  1 return (T) map;
1357    }
1358   
1359  3657 if (clazz == JSONObject.class) {
1360  1 return (T) new JSONObject(map);
1361    }
1362   
1363  3656 if (config == null) {
1364  3 config = ParserConfig.getGlobalInstance();
1365    }
1366   
1367  3656 JavaBeanDeserializer javaBeanDeser = null;
1368  3656 ObjectDeserializer deserializer = config.getDeserializer(clazz);
1369  3656 if (deserializer instanceof JavaBeanDeserializer) {
1370  3654 javaBeanDeser = (JavaBeanDeserializer) deserializer;
1371    }
1372   
1373  3656 if(javaBeanDeser == null){
1374  2 throw new JSONException("can not get javaBeanDeserializer. " + clazz.getName());
1375    }
1376  3654 return (T) javaBeanDeser.createInstance(map, config);
1377    } catch(Exception e){
1378  17 Test failure here throw new JSONException(e.getMessage(), e);
1379    }
1380    }
1381   
 
1382  4 toggle private static void addBaseClassMappings(){
1383  4 mappings.put("byte", byte.class);
1384  4 mappings.put("short", short.class);
1385  4 mappings.put("int", int.class);
1386  4 mappings.put("long", long.class);
1387  4 mappings.put("float", float.class);
1388  4 mappings.put("double", double.class);
1389  4 mappings.put("boolean", boolean.class);
1390  4 mappings.put("char", char.class);
1391  4 mappings.put("[byte", byte[].class);
1392  4 mappings.put("[short", short[].class);
1393  4 mappings.put("[int", int[].class);
1394  4 mappings.put("[long", long[].class);
1395  4 mappings.put("[float", float[].class);
1396  4 mappings.put("[double", double[].class);
1397  4 mappings.put("[boolean", boolean[].class);
1398  4 mappings.put("[char", char[].class);
1399  4 mappings.put("[B", byte[].class);
1400  4 mappings.put("[S", short[].class);
1401  4 mappings.put("[I", int[].class);
1402  4 mappings.put("[J", long[].class);
1403  4 mappings.put("[F", float[].class);
1404  4 mappings.put("[D", double[].class);
1405  4 mappings.put("[C", char[].class);
1406  4 mappings.put("[Z", boolean[].class);
1407  4 Class<?>[] classes = new Class[]{
1408    Object.class,
1409    java.lang.Cloneable.class,
1410    loadClass("java.lang.AutoCloseable"),
1411    java.lang.Exception.class,
1412    java.lang.RuntimeException.class,
1413    java.lang.IllegalAccessError.class,
1414    java.lang.IllegalAccessException.class,
1415    java.lang.IllegalArgumentException.class,
1416    java.lang.IllegalMonitorStateException.class,
1417    java.lang.IllegalStateException.class,
1418    java.lang.IllegalThreadStateException.class,
1419    java.lang.IndexOutOfBoundsException.class,
1420    java.lang.InstantiationError.class,
1421    java.lang.InstantiationException.class,
1422    java.lang.InternalError.class,
1423    java.lang.InterruptedException.class,
1424    java.lang.LinkageError.class,
1425    java.lang.NegativeArraySizeException.class,
1426    java.lang.NoClassDefFoundError.class,
1427    java.lang.NoSuchFieldError.class,
1428    java.lang.NoSuchFieldException.class,
1429    java.lang.NoSuchMethodError.class,
1430    java.lang.NoSuchMethodException.class,
1431    java.lang.NullPointerException.class,
1432    java.lang.NumberFormatException.class,
1433    java.lang.OutOfMemoryError.class,
1434    java.lang.SecurityException.class,
1435    java.lang.StackOverflowError.class,
1436    java.lang.StringIndexOutOfBoundsException.class,
1437    java.lang.TypeNotPresentException.class,
1438    java.lang.VerifyError.class,
1439    java.lang.StackTraceElement.class,
1440    java.util.HashMap.class,
1441    java.util.Hashtable.class,
1442    java.util.TreeMap.class,
1443    java.util.IdentityHashMap.class,
1444    java.util.WeakHashMap.class,
1445    java.util.LinkedHashMap.class,
1446    java.util.HashSet.class,
1447    java.util.LinkedHashSet.class,
1448    java.util.TreeSet.class,
1449    java.util.ArrayList.class,
1450    java.util.concurrent.TimeUnit.class,
1451    java.util.concurrent.ConcurrentHashMap.class,
1452    loadClass("java.util.concurrent.ConcurrentSkipListMap"),
1453    loadClass("java.util.concurrent.ConcurrentSkipListSet"),
1454    java.util.concurrent.atomic.AtomicInteger.class,
1455    java.util.concurrent.atomic.AtomicLong.class,
1456    java.util.Collections.EMPTY_MAP.getClass(),
1457    java.lang.Boolean.class,
1458    java.lang.Character.class,
1459    java.lang.Byte.class,
1460    java.lang.Short.class,
1461    java.lang.Integer.class,
1462    java.lang.Long.class,
1463    java.lang.Float.class,
1464    java.lang.Double.class,
1465    java.lang.Number.class,
1466    java.lang.String.class,
1467    java.math.BigDecimal.class,
1468    java.math.BigInteger.class,
1469    java.util.BitSet.class,
1470    java.util.Calendar.class,
1471    java.util.Date.class,
1472    java.util.Locale.class,
1473    java.util.UUID.class,
1474    java.sql.Time.class,
1475    java.sql.Date.class,
1476    java.sql.Timestamp.class,
1477    java.text.SimpleDateFormat.class,
1478    com.alibaba.fastjson.JSONObject.class,
1479    com.alibaba.fastjson.JSONPObject.class,
1480    com.alibaba.fastjson.JSONArray.class,
1481    };
1482  4 for(Class clazz : classes){
1483  292 if(clazz == null){
1484  0 continue;
1485    }
1486  292 mappings.put(clazz.getName(), clazz);
1487    }
1488   
1489  4 String[] w = new String[]{
1490    "java.util.Collections$UnmodifiableMap"
1491    };
1492  4 for(String className : w){
1493  4 Class<?> clazz = loadClass(className);
1494  4 if(clazz == null){
1495  0 break;
1496    }
1497  4 mappings.put(clazz.getName(), clazz);
1498    }
1499   
1500  4 String[] awt = new String[]{
1501    "java.awt.Rectangle",
1502    "java.awt.Point",
1503    "java.awt.Font",
1504    "java.awt.Color"};
1505  4 for(String className : awt){
1506  16 Class<?> clazz = loadClass(className);
1507  16 if(clazz == null){
1508  0 break;
1509    }
1510  16 mappings.put(clazz.getName(), clazz);
1511    }
1512   
1513  4 String[] spring = new String[]{
1514    "org.springframework.util.LinkedMultiValueMap",
1515    "org.springframework.util.LinkedCaseInsensitiveMap",
1516    "org.springframework.remoting.support.RemoteInvocation",
1517    "org.springframework.remoting.support.RemoteInvocationResult",
1518    "org.springframework.security.web.savedrequest.DefaultSavedRequest",
1519    "org.springframework.security.web.savedrequest.SavedCookie",
1520    "org.springframework.security.web.csrf.DefaultCsrfToken",
1521    "org.springframework.security.web.authentication.WebAuthenticationDetails",
1522    "org.springframework.security.core.context.SecurityContextImpl",
1523    "org.springframework.security.authentication.UsernamePasswordAuthenticationToken",
1524    "org.springframework.security.core.authority.SimpleGrantedAuthority",
1525    "org.springframework.security.core.userdetails.User",
1526    "org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken",
1527    "org.springframework.security.oauth2.common.DefaultOAuth2AccessToken",
1528    "org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken",
1529    "org.springframework.cache.support.NullValue",
1530    "org.springframework.jdbc.UncategorizedSQLException",
1531    "org.springframework.dao.CannotAcquireLockException",
1532    "org.springframework.dao.DuplicateKeyException",
1533    "org.springframework.dao.QueryTimeoutException",
1534    "org.springframework.dao.TransientDataAccessException",
1535    "org.springframework.dao.TypeMismatchDataAccessException",
1536    "org.springframework.dao.UncategorizedDataAccessException",
1537    "org.springframework.dao.DataAccessResourceFailureException",
1538    };
1539  4 for(String className : spring){
1540  96 Class<?> clazz = loadClass(className);
1541  96 if(clazz == null){
1542  4 continue;
1543    }
1544  92 mappings.put(clazz.getName(), clazz);
1545    }
1546   
1547  4 String[] sofa = new String[] {
1548    "com.alipay.sofa.rpc.core.exception.SofaTimeOutException",
1549    };
1550   
1551  4 for(String className : sofa){
1552  4 Class<?> clazz = loadClass(className);
1553  4 if(clazz == null){
1554  4 continue;
1555    }
1556  0 mappings.put(clazz.getName(), clazz);
1557    }
1558    }
1559   
 
1560  3 toggle public static void clearClassMapping(){
1561  3 mappings.clear();
1562  3 addBaseClassMappings();
1563    }
1564   
 
1565  29 toggle public static void addMapping(String className, Class<?> clazz) {
1566  29 mappings.put(className, clazz);
1567    }
1568   
 
1569  140 toggle public static Class<?> loadClass(String className){
1570  140 return loadClass(className, null);
1571    }
1572   
 
1573  1500 toggle public static boolean isPath(Class<?> clazz){
1574  1500 if(pathClass == null && !pathClass_error){
1575  1 try{
1576  1 pathClass = Class.forName("java.nio.file.Path");
1577    } catch(Throwable ex){
1578  0 pathClass_error = true;
1579    }
1580    }
1581  1500 if(pathClass != null){
1582  1500 return pathClass.isAssignableFrom(clazz);
1583    }
1584  0 return false;
1585    }
1586   
 
1587  12822 toggle public static Class<?> getClassFromMapping(String className){
1588  12822 return mappings.get(className);
1589    }
1590   
 
1591  152 toggle public static Class<?> loadClass(String className, ClassLoader classLoader) {
1592  152 return loadClass(className, classLoader, false);
1593    }
1594   
 
1595  282 toggle public static Class<?> loadClass(String className, ClassLoader classLoader, boolean cache) {
1596  282 if(className == null || className.length() == 0 || className.length() > 128){
1597  2 return null;
1598    }
1599   
1600  280 Class<?> clazz = mappings.get(className);
1601  280 if(clazz != null){
1602  32 return clazz;
1603    }
1604   
1605  248 if(className.charAt(0) == '['){
1606  6 Class<?> componentType = loadClass(className.substring(1), classLoader);
1607  6 return Array.newInstance(componentType, 0).getClass();
1608    }
1609   
1610  242 if(className.startsWith("L") && className.endsWith(";")){
1611  3 String newClassName = className.substring(1, className.length() - 1);
1612  3 return loadClass(newClassName, classLoader);
1613    }
1614   
1615  239 try{
1616  239 if(classLoader != null){
1617  2 clazz = classLoader.loadClass(className);
1618  1 if (cache) {
1619  0 mappings.put(className, clazz);
1620    }
1621  1 return clazz;
1622    }
1623    } catch(Throwable e){
1624  1 e.printStackTrace();
1625    // skip
1626    }
1627  238 try{
1628  238 ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
1629  238 if(contextClassLoader != null && contextClassLoader != classLoader){
1630  237 clazz = contextClassLoader.loadClass(className);
1631  216 if (cache) {
1632  71 mappings.put(className, clazz);
1633    }
1634  216 return clazz;
1635    }
1636    } catch(Throwable e){
1637    // skip
1638    }
1639  22 try{
1640  22 clazz = Class.forName(className);
1641  1 if (cache) {
1642  0 mappings.put(className, clazz);
1643    }
1644  1 return clazz;
1645    } catch(Throwable e){
1646    // skip
1647    }
1648  21 return clazz;
1649    }
1650   
 
1651  21 toggle public static SerializeBeanInfo buildBeanInfo(Class<?> beanType //
1652    , Map<String,String> aliasMap //
1653    , PropertyNamingStrategy propertyNamingStrategy){
1654  21 return buildBeanInfo(beanType, aliasMap, propertyNamingStrategy, false);
1655    }
1656   
 
1657  1475 toggle public static SerializeBeanInfo buildBeanInfo(Class<?> beanType //
1658    , Map<String,String> aliasMap //
1659    , PropertyNamingStrategy propertyNamingStrategy //
1660    , boolean fieldBased //
1661    ){
1662  1475 JSONType jsonType = TypeUtils.getAnnotation(beanType,JSONType.class);
1663  1475 String[] orders = null;
1664  1475 final int features;
1665  1475 String typeName = null, typeKey = null;
1666  1475 if(jsonType != null){
1667  55 orders = jsonType.orders();
1668   
1669  55 typeName = jsonType.typeName();
1670  55 if(typeName.length() == 0){
1671  50 typeName = null;
1672    }
1673   
1674  55 PropertyNamingStrategy jsonTypeNaming = jsonType.naming();
1675  55 if (jsonTypeNaming != PropertyNamingStrategy.CamelCase) {
1676  3 propertyNamingStrategy = jsonTypeNaming;
1677    }
1678   
1679  55 features = SerializerFeature.of(jsonType.serialzeFeatures());
1680  55 for(Class<?> supperClass = beanType.getSuperclass()
1681  60 ; supperClass != null && supperClass != Object.class
1682    ; supperClass = supperClass.getSuperclass()){
1683  12 JSONType superJsonType = TypeUtils.getAnnotation(supperClass,JSONType.class);
1684  12 if(superJsonType == null){
1685  7 break;
1686    }
1687  5 typeKey = superJsonType.typeKey();
1688  5 if(typeKey.length() != 0){
1689  0 break;
1690    }
1691    }
1692   
1693  55 for(Class<?> interfaceClass : beanType.getInterfaces()){
1694  5 JSONType superJsonType = TypeUtils.getAnnotation(interfaceClass,JSONType.class);
1695  5 if(superJsonType != null){
1696  2 typeKey = superJsonType.typeKey();
1697  2 if(typeKey.length() != 0){
1698  2 break;
1699    }
1700    }
1701    }
1702   
1703  55 if(typeKey != null && typeKey.length() == 0){
1704  4 typeKey = null;
1705    }
1706    } else{
1707  1420 features = 0;
1708    }
1709    // fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
1710  1475 Map<String,Field> fieldCacheMap = new HashMap<String,Field>();
1711  1475 ParserConfig.parserAllFieldToCache(beanType, fieldCacheMap);
1712  1475 List<FieldInfo> fieldInfoList = fieldBased
1713    ? computeGettersWithFieldBase(beanType, aliasMap, false, propertyNamingStrategy) //
1714    : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, false, propertyNamingStrategy);
1715  1475 FieldInfo[] fields = new FieldInfo[fieldInfoList.size()];
1716  1475 fieldInfoList.toArray(fields);
1717  1475 FieldInfo[] sortedFields;
1718  1475 List<FieldInfo> sortedFieldList;
1719  1475 if(orders != null && orders.length != 0){
1720  9 sortedFieldList = fieldBased
1721    ? computeGettersWithFieldBase(beanType, aliasMap, true, propertyNamingStrategy) //
1722    : computeGetters(beanType, jsonType, aliasMap, fieldCacheMap, true, propertyNamingStrategy);
1723    } else{
1724  1466 sortedFieldList = new ArrayList<FieldInfo>(fieldInfoList);
1725  1466 Collections.sort(sortedFieldList);
1726    }
1727  1475 sortedFields = new FieldInfo[sortedFieldList.size()];
1728  1475 sortedFieldList.toArray(sortedFields);
1729  1475 if(Arrays.equals(sortedFields, fields)){
1730  1067 sortedFields = fields;
1731    }
1732  1475 return new SerializeBeanInfo(beanType, jsonType, typeName, typeKey, features, fields, sortedFields);
1733    }
1734   
 
1735  2 toggle public static List<FieldInfo> computeGettersWithFieldBase(
1736    Class<?> clazz, //
1737    Map<String,String> aliasMap, //
1738    boolean sorted, //
1739    PropertyNamingStrategy propertyNamingStrategy){
1740  2 Map<String,FieldInfo> fieldInfoMap = new LinkedHashMap<String,FieldInfo>();
1741  7 for(Class<?> currentClass = clazz; currentClass != null; currentClass = currentClass.getSuperclass()){
1742  5 Field[] fields = currentClass.getDeclaredFields();
1743  5 computeFields(currentClass, aliasMap, propertyNamingStrategy, fieldInfoMap, fields);
1744    }
1745  2 return getFieldInfos(clazz, sorted, fieldInfoMap);
1746    }
1747   
 
1748  1 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String,String> aliasMap){
1749  1 return computeGetters(clazz, aliasMap, true);
1750    }
1751   
 
1752  1 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String,String> aliasMap, boolean sorted){
1753  1 JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
1754  1 Map<String,Field> fieldCacheMap = new HashMap<String,Field>();
1755  1 ParserConfig.parserAllFieldToCache(clazz, fieldCacheMap);
1756  1 return computeGetters(clazz, jsonType, aliasMap, fieldCacheMap, sorted, PropertyNamingStrategy.CamelCase);
1757    }
1758   
 
1759  1483 toggle public static List<FieldInfo> computeGetters(Class<?> clazz, //
1760    JSONType jsonType, //
1761    Map<String,String> aliasMap, //
1762    Map<String,Field> fieldCacheMap, //
1763    boolean sorted, //
1764    PropertyNamingStrategy propertyNamingStrategy //
1765    ){
1766  1483 Map<String,FieldInfo> fieldInfoMap = new LinkedHashMap<String,FieldInfo>();
1767  1483 boolean kotlin = TypeUtils.isKotlin(clazz);
1768    // for kotlin
1769  1483 Constructor[] constructors = null;
1770  1483 Annotation[][] paramAnnotationArrays = null;
1771  1483 String[] paramNames = null;
1772  1483 short[] paramNameMapping = null;
1773  1483 Method[] methods = clazz.getMethods();
1774  1483 for(Method method : methods){
1775  18869 String methodName = method.getName();
1776  18869 int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
1777  18868 String label = null;
1778  18869 if(Modifier.isStatic(method.getModifiers())){
1779  148 continue;
1780    }
1781  18722 if(method.getReturnType().equals(Void.TYPE)){
1782  9816 continue;
1783    }
1784  8906 if(method.getParameterTypes().length != 0){
1785  1628 continue;
1786    }
1787  7278 if(method.getReturnType() == ClassLoader.class){
1788  1 continue;
1789    }
1790   
1791  7277 if(methodName.equals("getMetaClass")
1792    && method.getReturnType().getName().equals("groovy.lang.MetaClass")){
1793  2 continue;
1794    }
1795  7275 if(methodName.equals("getSuppressed")
1796    && method.getDeclaringClass() == Throwable.class){
1797  8 continue;
1798    }
1799   
1800  7267 if(kotlin && isKotlinIgnore(clazz, methodName)){
1801  0 continue;
1802    }
1803    /**
1804    * 如果在属性或者方法上存在JSONField注解,并且定制了name属性,不以类上的propertyNamingStrategy设置为准,以此字段的JSONField的name定制为准。
1805    */
1806  7267 Boolean fieldAnnotationAndNameExists = false;
1807  7266 JSONField annotation = TypeUtils.getAnnotation(method, JSONField.class);
1808  7266 if(annotation == null){
1809  7193 annotation = getSuperMethodAnnotation(clazz, method);
1810    }
1811  7267 if(annotation == null && kotlin){
1812  168 if(constructors == null){
1813  20 constructors = clazz.getDeclaredConstructors();
1814  20 Constructor creatorConstructor = TypeUtils.getKoltinConstructor(constructors);
1815  20 if(creatorConstructor != null){
1816  20 paramAnnotationArrays = TypeUtils.getParameterAnnotations(creatorConstructor);
1817  20 paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
1818  20 if(paramNames != null){
1819  20 String[] paramNames_sorted = new String[paramNames.length];
1820  20 System.arraycopy(paramNames, 0, paramNames_sorted, 0, paramNames.length);
1821   
1822  20 Arrays.sort(paramNames_sorted);
1823  20 paramNameMapping = new short[paramNames.length];
1824  71 for(short p = 0; p < paramNames.length; p++){
1825  51 int index = Arrays.binarySearch(paramNames_sorted, paramNames[p]);
1826  51 paramNameMapping[index] = p;
1827    }
1828  20 paramNames = paramNames_sorted;
1829    }
1830    }
1831    }
1832  168 if(paramNames != null && paramNameMapping != null && methodName.startsWith("get")){
1833  85 String propertyName = decapitalize(methodName.substring(3));
1834  85 int p = Arrays.binarySearch(paramNames, propertyName);
1835  85 if (p < 0) {
1836  98 for (int i = 0; i < paramNames.length; i++) {
1837  64 if (propertyName.equalsIgnoreCase(paramNames[i])) {
1838  2 p = i;
1839  2 break;
1840    }
1841    }
1842    }
1843  85 if(p >= 0){
1844  51 short index = paramNameMapping[p];
1845  51 Annotation[] paramAnnotations = paramAnnotationArrays[index];
1846  51 if(paramAnnotations != null){
1847  51 for(Annotation paramAnnotation : paramAnnotations){
1848  22 if(paramAnnotation instanceof JSONField){
1849  22 annotation = (JSONField) paramAnnotation;
1850  22 break;
1851    }
1852    }
1853    }
1854  51 if(annotation == null){
1855  29 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1856  29 if(field != null){
1857  29 annotation = TypeUtils.getAnnotation(field, JSONField.class);
1858    }
1859    }
1860    }
1861    }
1862    }
1863  7267 if(annotation != null){
1864  102 if(!annotation.serialize()){
1865  8 continue;
1866    }
1867  94 ordinal = annotation.ordinal();
1868  94 serialzeFeatures = SerializerFeature.of(annotation.serialzeFeatures());
1869  94 parserFeatures = Feature.of(annotation.parseFeatures());
1870  94 if(annotation.name().length() != 0){
1871  44 String propertyName = annotation.name();
1872  44 if(aliasMap != null){
1873  1 propertyName = aliasMap.get(propertyName);
1874  1 if(propertyName == null){
1875  1 continue;
1876    }
1877    }
1878  43 FieldInfo fieldInfo = new FieldInfo(propertyName, method, null, clazz, null, ordinal,
1879    serialzeFeatures, parserFeatures, annotation, null, label);
1880  43 fieldInfoMap.put(propertyName, fieldInfo);
1881  43 continue;
1882    }
1883  50 if(annotation.label().length() != 0){
1884  12 label = annotation.label();
1885    }
1886    }
1887  7215 if(methodName.startsWith("get")){
1888  4057 if(methodName.length() < 4){
1889  7 continue;
1890    }
1891  4051 if(methodName.equals("getClass")){
1892  1471 continue;
1893    }
1894  2580 if(methodName.equals("getDeclaringClass") && clazz.isEnum()){
1895  8 continue;
1896    }
1897  2572 char c3 = methodName.charAt(3);
1898  2572 String propertyName;
1899  2572 if(Character.isUpperCase(c3) //
1900    || c3 > 512 // for unicode method name
1901    ){
1902  2545 if(compatibleWithJavaBean){
1903  1 propertyName = decapitalize(methodName.substring(3));
1904    } else{
1905  2544 propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
1906    }
1907  2545 propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 3);
1908  27 } else if(c3 == '_'){
1909  2 propertyName = methodName.substring(4);
1910  25 } else if(c3 == 'f'){
1911  1 propertyName = methodName.substring(3);
1912  24 } else if(methodName.length() >= 5 && Character.isUpperCase(methodName.charAt(4))){
1913  17 propertyName = decapitalize(methodName.substring(3));
1914    } else{
1915  7 continue;
1916    }
1917  2564 boolean ignore = isJSONTypeIgnore(clazz, propertyName);
1918  2565 if(ignore){
1919  11 continue;
1920    }
1921    //假如bean的field很多的情况一下,轮询时将大大降低效率
1922  2554 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1923  2554 if(field == null && propertyName.length() > 1){
1924  124 char ch = propertyName.charAt(1);
1925  124 if(ch >= 'A' && ch <= 'Z'){
1926  3 String javaBeanCompatiblePropertyName = decapitalize(methodName.substring(3));
1927  3 field = ParserConfig.getFieldFromCache(javaBeanCompatiblePropertyName, fieldCacheMap);
1928    }
1929    }
1930  2554 JSONField fieldAnnotation = null;
1931  2554 if(field != null){
1932  2429 fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
1933  2429 if(fieldAnnotation != null){
1934  106 if(!fieldAnnotation.serialize()){
1935  9 continue;
1936    }
1937  97 ordinal = fieldAnnotation.ordinal();
1938  97 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
1939  97 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
1940  97 if(fieldAnnotation.name().length() != 0){
1941  34 fieldAnnotationAndNameExists = true;
1942  34 propertyName = fieldAnnotation.name();
1943  34 if(aliasMap != null){
1944  1 propertyName = aliasMap.get(propertyName);
1945  1 if(propertyName == null){
1946  1 continue;
1947    }
1948    }
1949    }
1950  96 if(fieldAnnotation.label().length() != 0){
1951  0 label = fieldAnnotation.label();
1952    }
1953    }
1954    }
1955  2544 if(aliasMap != null){
1956  5 propertyName = aliasMap.get(propertyName);
1957  5 if(propertyName == null){
1958  3 continue;
1959    }
1960    }
1961  2540 if(propertyNamingStrategy != null && !fieldAnnotationAndNameExists){
1962  265 propertyName = propertyNamingStrategy.translate(propertyName);
1963    }
1964  2539 FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
1965    annotation, fieldAnnotation, label);
1966  2541 fieldInfoMap.put(propertyName, fieldInfo);
1967    }
1968  5697 if(methodName.startsWith("is")){
1969  91 if(methodName.length() < 3){
1970  7 continue;
1971    }
1972  84 if(method.getReturnType() != Boolean.TYPE
1973    && method.getReturnType() != Boolean.class){
1974  1 continue;
1975    }
1976  83 char c2 = methodName.charAt(2);
1977  83 String propertyName;
1978  83 if(Character.isUpperCase(c2)){
1979  74 if(compatibleWithJavaBean){
1980  1 propertyName = decapitalize(methodName.substring(2));
1981    } else{
1982  73 propertyName = Character.toLowerCase(methodName.charAt(2)) + methodName.substring(3);
1983    }
1984  74 propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 2);
1985  9 } else if(c2 == '_'){
1986  1 propertyName = methodName.substring(3);
1987  8 } else if(c2 == 'f'){
1988  1 propertyName = methodName.substring(2);
1989    } else{
1990  7 continue;
1991    }
1992  76 boolean ignore = isJSONTypeIgnore(clazz, propertyName);
1993  76 if(ignore){
1994  1 continue;
1995    }
1996  75 Field field = ParserConfig.getFieldFromCache(propertyName, fieldCacheMap);
1997  75 if(field == null){
1998  21 field = ParserConfig.getFieldFromCache(methodName, fieldCacheMap);
1999    }
2000  75 JSONField fieldAnnotation = null;
2001  75 if(field != null){
2002  59 fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
2003  59 if(fieldAnnotation != null){
2004  7 if(!fieldAnnotation.serialize()){
2005  3 continue;
2006    }
2007  4 ordinal = fieldAnnotation.ordinal();
2008  4 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
2009  4 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
2010  4 if(fieldAnnotation.name().length() != 0){
2011  3 propertyName = fieldAnnotation.name();
2012  3 if(aliasMap != null){
2013  1 propertyName = aliasMap.get(propertyName);
2014  1 if(propertyName == null){
2015  1 continue;
2016    }
2017    }
2018    }
2019  3 if(fieldAnnotation.label().length() != 0){
2020  0 label = fieldAnnotation.label();
2021    }
2022    }
2023    }
2024  71 if(aliasMap != null){
2025  1 propertyName = aliasMap.get(propertyName);
2026  1 if(propertyName == null){
2027  1 continue;
2028    }
2029    }
2030  70 if(propertyNamingStrategy != null){
2031  1 propertyName = propertyNamingStrategy.translate(propertyName);
2032    }
2033    //优先选择get
2034  70 if(fieldInfoMap.containsKey(propertyName)){
2035  3 continue;
2036    }
2037  67 FieldInfo fieldInfo = new FieldInfo(propertyName, method, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
2038    annotation, fieldAnnotation, label);
2039  67 fieldInfoMap.put(propertyName, fieldInfo);
2040    }
2041    }
2042  1483 Field[] fields = clazz.getFields();
2043  1483 computeFields(clazz, aliasMap, propertyNamingStrategy, fieldInfoMap, fields);
2044  1483 return getFieldInfos(clazz, sorted, fieldInfoMap);
2045    }
2046   
 
2047  1485 toggle private static List<FieldInfo> getFieldInfos(Class<?> clazz, boolean sorted, Map<String,FieldInfo> fieldInfoMap){
2048  1485 List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
2049  1485 String[] orders = null;
2050  1485 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2051  1485 if(annotation != null){
2052  64 orders = annotation.orders();
2053    }
2054  1485 if(orders != null && orders.length > 0){
2055  18 LinkedHashMap<String,FieldInfo> map = new LinkedHashMap<String,FieldInfo>(fieldInfoList.size());
2056  18 for(FieldInfo field : fieldInfoMap.values()){
2057  56 map.put(field.name, field);
2058    }
2059  18 int i = 0;
2060  18 for(String item : orders){
2061  52 FieldInfo field = map.get(item);
2062  52 if(field != null){
2063  50 fieldInfoList.add(field);
2064  50 map.remove(item);
2065    }
2066    }
2067  18 for(FieldInfo field : map.values()){
2068  6 fieldInfoList.add(field);
2069    }
2070    } else{
2071  1467 for(FieldInfo fieldInfo : fieldInfoMap.values()){
2072  9793 fieldInfoList.add(fieldInfo);
2073    }
2074  1467 if(sorted){
2075  1 Collections.sort(fieldInfoList);
2076    }
2077    }
2078  1485 return fieldInfoList;
2079    }
2080   
 
2081  1488 toggle private static void computeFields(
2082    Class<?> clazz, //
2083    Map<String,String> aliasMap, //
2084    PropertyNamingStrategy propertyNamingStrategy, //
2085    Map<String,FieldInfo> fieldInfoMap, //
2086    Field[] fields){
2087  1488 for(Field field : fields){
2088  7350 if(Modifier.isStatic(field.getModifiers())){
2089  102 continue;
2090    }
2091  7248 JSONField fieldAnnotation = TypeUtils.getAnnotation(field, JSONField.class);
2092  7248 int ordinal = 0, serialzeFeatures = 0, parserFeatures = 0;
2093  7248 String propertyName = field.getName();
2094  7248 String label = null;
2095  7248 if(fieldAnnotation != null){
2096  86 if(!fieldAnnotation.serialize()){
2097  3 continue;
2098    }
2099  83 ordinal = fieldAnnotation.ordinal();
2100  83 serialzeFeatures = SerializerFeature.of(fieldAnnotation.serialzeFeatures());
2101  83 parserFeatures = Feature.of(fieldAnnotation.parseFeatures());
2102  83 if(fieldAnnotation.name().length() != 0){
2103  27 propertyName = fieldAnnotation.name();
2104    }
2105  83 if(fieldAnnotation.label().length() != 0){
2106  0 label = fieldAnnotation.label();
2107    }
2108    }
2109  7245 if(aliasMap != null){
2110  2 propertyName = aliasMap.get(propertyName);
2111  2 if(propertyName == null){
2112  1 continue;
2113    }
2114    }
2115  7244 if(propertyNamingStrategy != null){
2116  4 propertyName = propertyNamingStrategy.translate(propertyName);
2117    }
2118  7244 if(!fieldInfoMap.containsKey(propertyName)){
2119  7207 FieldInfo fieldInfo = new FieldInfo(propertyName, null, field, clazz, null, ordinal, serialzeFeatures, parserFeatures,
2120    null, fieldAnnotation, label);
2121  7207 fieldInfoMap.put(propertyName, fieldInfo);
2122    }
2123    }
2124    }
2125   
 
2126  2619 toggle private static String getPropertyNameByCompatibleFieldName(Map<String,Field> fieldCacheMap, String methodName,
2127    String propertyName, int fromIdx){
2128  2618 if(compatibleWithFieldName){
2129  0 if(!fieldCacheMap.containsKey(propertyName)){
2130  0 String tempPropertyName = methodName.substring(fromIdx);
2131  0 return fieldCacheMap.containsKey(tempPropertyName) ? tempPropertyName : propertyName;
2132    }
2133    }
2134  2618 return propertyName;
2135    }
2136   
 
2137  11623 toggle public static JSONField getSuperMethodAnnotation(final Class<?> clazz, final Method method){
2138  11623 Class<?>[] interfaces = clazz.getInterfaces();
2139  11623 if(interfaces.length > 0){
2140  1618 Class<?>[] types = method.getParameterTypes();
2141  1618 for(Class<?> interfaceClass : interfaces){
2142  1690 for(Method interfaceMethod : interfaceClass.getMethods()){
2143  1934 Class<?>[] interfaceTypes = interfaceMethod.getParameterTypes();
2144  1934 if(interfaceTypes.length != types.length){
2145  950 continue;
2146    }
2147  984 if(!interfaceMethod.getName().equals(method.getName())){
2148  883 continue;
2149    }
2150  101 boolean match = true;
2151  115 for(int i = 0; i < types.length; ++i){
2152  18 if(!interfaceTypes[i].equals(types[i])){
2153  4 match = false;
2154  4 break;
2155    }
2156    }
2157  101 if(!match){
2158  4 continue;
2159    }
2160  97 JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class);
2161  97 if(annotation != null){
2162  7 return annotation;
2163    }
2164    }
2165    }
2166    }
2167  11617 Class<?> superClass = clazz.getSuperclass();
2168  11617 if(superClass == null){
2169  69 return null;
2170    }
2171  11548 if(Modifier.isAbstract(superClass.getModifiers())){
2172  279 Class<?>[] types = method.getParameterTypes();
2173  279 for(Method interfaceMethod : superClass.getMethods()){
2174  6605 Class<?>[] interfaceTypes = interfaceMethod.getParameterTypes();
2175  6605 if(interfaceTypes.length != types.length){
2176  3080 continue;
2177    }
2178  3525 if(!interfaceMethod.getName().equals(method.getName())){
2179  3295 continue;
2180    }
2181  230 boolean match = true;
2182  243 for(int i = 0; i < types.length; ++i){
2183  13 if(!interfaceTypes[i].equals(types[i])){
2184  0 match = false;
2185  0 break;
2186    }
2187    }
2188  230 if(!match){
2189  0 continue;
2190    }
2191  230 JSONField annotation = TypeUtils.getAnnotation(interfaceMethod, JSONField.class);
2192  230 if(annotation != null){
2193  1 return annotation;
2194    }
2195    }
2196    }
2197  11547 return null;
2198    }
2199   
 
2200  3107 toggle private static boolean isJSONTypeIgnore(Class<?> clazz, String propertyName){
2201  3107 JSONType jsonType = TypeUtils.getAnnotation(clazz,JSONType.class);
2202  3108 if(jsonType != null){
2203    // 1、新增 includes 支持,如果 JSONType 同时设置了includes 和 ignores 属性,则以includes为准。
2204    // 2、个人认为对于大小写敏感的Java和JS而言,使用 equals() 比 equalsIgnoreCase() 更好,改动的唯一风险就是向后兼容性的问题
2205    // 不过,相信开发者应该都是严格按照大小写敏感的方式进行属性设置的
2206  151 String[] fields = jsonType.includes();
2207  151 if(fields.length > 0){
2208  5 for(int i = 0; i < fields.length; i++){
2209  3 if(propertyName.equals(fields[i])){
2210  1 return false;
2211    }
2212    }
2213  2 return true;
2214    } else{
2215  148 fields = jsonType.ignores();
2216  182 for(int i = 0; i < fields.length; i++){
2217  44 if(propertyName.equals(fields[i])){
2218  10 return true;
2219    }
2220    }
2221    }
2222    }
2223  3095 if(clazz.getSuperclass() != Object.class && clazz.getSuperclass() != null){
2224  467 return isJSONTypeIgnore(clazz.getSuperclass(), propertyName);
2225    }
2226  2628 return false;
2227    }
2228   
 
2229  1299 toggle public static boolean isGenericParamType(Type type){
2230  1299 if(type instanceof ParameterizedType){
2231  329 return true;
2232    }
2233  970 if(type instanceof Class) {
2234  967 Type superType = ((Class<?>) type).getGenericSuperclass();
2235  967 return superType != Object.class && isGenericParamType(superType);
2236    }
2237  3 return false;
2238    }
2239   
 
2240  31 toggle public static Type getGenericParamType(Type type){
2241  31 if(type instanceof ParameterizedType){
2242  27 return type;
2243    }
2244  4 if(type instanceof Class){
2245  4 return getGenericParamType(((Class<?>) type).getGenericSuperclass());
2246    }
2247  0 return type;
2248    }
2249   
 
2250  5 toggle public static Type unwrapOptional(Type type){
2251  5 if(!optionalClassInited){
2252  1 try{
2253  1 optionalClass = Class.forName("java.util.Optional");
2254    } catch(Exception e){
2255    // skip
2256    } finally{
2257  1 optionalClassInited = true;
2258    }
2259    }
2260  5 if(type instanceof ParameterizedType){
2261  5 ParameterizedType parameterizedType = (ParameterizedType) type;
2262  5 if(parameterizedType.getRawType() == optionalClass){
2263  5 return parameterizedType.getActualTypeArguments()[0];
2264    }
2265    }
2266  0 return type;
2267    }
2268   
 
2269  253 toggle public static Class<?> getClass(Type type){
2270  253 if(type.getClass() == Class.class){
2271  164 return (Class<?>) type;
2272    }
2273   
2274  89 if(type instanceof ParameterizedType){
2275  68 return getClass(((ParameterizedType) type).getRawType());
2276    }
2277   
2278  21 if(type instanceof TypeVariable){
2279  15 Type boundType = ((TypeVariable<?>) type).getBounds()[0];
2280  15 if (boundType instanceof Class) {
2281  15 return (Class) boundType;
2282    }
2283  0 return getClass(boundType);
2284    }
2285   
2286  6 if(type instanceof WildcardType){
2287  6 Type[] upperBounds = ((WildcardType) type).getUpperBounds();
2288  6 if (upperBounds.length == 1) {
2289  6 return getClass(upperBounds[0]);
2290    }
2291    }
2292   
2293  0 return Object.class;
2294    }
2295   
 
2296  5306 toggle public static Field getField(Class<?> clazz, String fieldName, Field[] declaredFields){
2297  5306 for(Field field : declaredFields){
2298  169682 String itemName = field.getName();
2299  169682 if(fieldName.equals(itemName)){
2300  4972 return field;
2301    }
2302   
2303  164710 char c0, c1;
2304  ? if (fieldName.length() > 2
2305    && (c0 = fieldName.charAt(0)) >= 'a' && c0 <= 'z'
2306    && (c1 = fieldName.charAt(1)) >= 'A' && c1 <= 'Z'
2307    && fieldName.equalsIgnoreCase(itemName)) {
2308  8 return field;
2309    }
2310    }
2311  326 Class<?> superClass = clazz.getSuperclass();
2312  326 if(superClass != null && superClass != Object.class){
2313  167 return getField(superClass, fieldName, superClass.getDeclaredFields());
2314    }
2315  159 return null;
2316    }
2317   
2318    /**
2319    * @deprecated
2320    */
 
2321  2 toggle public static int getSerializeFeatures(Class<?> clazz){
2322  2 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2323  2 if(annotation == null){
2324  1 return 0;
2325    }
2326  1 return SerializerFeature.of(annotation.serialzeFeatures());
2327    }
2328   
 
2329  2695 toggle public static int getParserFeatures(Class<?> clazz){
2330  2695 JSONType annotation = TypeUtils.getAnnotation(clazz,JSONType.class);
2331  2695 if(annotation == null){
2332  2576 return 0;
2333    }
2334  119 return Feature.of(annotation.parseFeatures());
2335    }
2336   
 
2337  147 toggle public static String decapitalize(String name){
2338  147 if(name == null || name.length() == 0){
2339  0 return name;
2340    }
2341  147 if(name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){
2342  9 return name;
2343    }
2344  138 char[] chars = name.toCharArray();
2345  138 chars[0] = Character.toLowerCase(chars[0]);
2346  138 return new String(chars);
2347    }
2348   
 
2349  35299 toggle static void setAccessible(AccessibleObject obj){
2350  35298 if(!setAccessibleEnable){
2351  0 return;
2352    }
2353  35300 if(obj.isAccessible()){
2354  9913 return;
2355    }
2356  25387 try{
2357  25387 obj.setAccessible(true);
2358    } catch(AccessControlException error){
2359  0 setAccessibleEnable = false;
2360    }
2361    }
2362   
 
2363  447 toggle public static Type getCollectionItemType(Type fieldType) {
2364  447 if (fieldType instanceof ParameterizedType) {
2365  393 return getCollectionItemType((ParameterizedType) fieldType);
2366    }
2367  54 if (fieldType instanceof Class<?>) {
2368  40 return getCollectionItemType((Class<?>) fieldType);
2369    }
2370  14 return Object.class;
2371    }
2372   
 
2373  40 toggle private static Type getCollectionItemType(Class<?> clazz) {
2374  40 return clazz.getName().startsWith("java.")
2375    ? Object.class
2376    : getCollectionItemType(getCollectionSuperType(clazz));
2377    }
2378   
 
2379  852 toggle private static Type getCollectionItemType(ParameterizedType parameterizedType) {
2380  852 Type rawType = parameterizedType.getRawType();
2381  852 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
2382  852 if (rawType == Collection.class) {
2383  393 return getWildcardTypeUpperBounds(actualTypeArguments[0]);
2384    }
2385  459 Class<?> rawClass = (Class<?>) rawType;
2386  459 Map<TypeVariable, Type> actualTypeMap = createActualTypeMap(rawClass.getTypeParameters(), actualTypeArguments);
2387  459 Type superType = getCollectionSuperType(rawClass);
2388  459 if (superType instanceof ParameterizedType) {
2389  459 Class<?> superClass = getRawClass(superType);
2390  459 Type[] superClassTypeParameters = ((ParameterizedType) superType).getActualTypeArguments();
2391  459 return superClassTypeParameters.length > 0
2392    ? getCollectionItemType(makeParameterizedType(superClass, superClassTypeParameters, actualTypeMap))
2393    : getCollectionItemType(superClass);
2394    }
2395  0 return getCollectionItemType((Class<?>) superType);
2396    }
2397   
 
2398  475 toggle private static Type getCollectionSuperType(Class<?> clazz) {
2399  475 Type assignable = null;
2400  475 for (Type type : clazz.getGenericInterfaces()) {
2401  554 Class<?> rawClass = getRawClass(type);
2402  554 if (rawClass == Collection.class) {
2403  367 return type;
2404    }
2405  187 if (Collection.class.isAssignableFrom(rawClass)) {
2406  83 assignable = type;
2407    }
2408    }
2409  108 return assignable == null ? clazz.getGenericSuperclass() : assignable;
2410    }
2411   
 
2412  459 toggle private static Map<TypeVariable, Type> createActualTypeMap(TypeVariable[] typeParameters, Type[] actualTypeArguments) {
2413  459 int length = typeParameters.length;
2414  459 Map<TypeVariable, Type> actualTypeMap = new HashMap<TypeVariable, Type>(length);
2415  927 for (int i = 0; i < length; i++) {
2416  468 actualTypeMap.put(typeParameters[i], actualTypeArguments[i]);
2417    }
2418  459 return actualTypeMap;
2419    }
2420   
 
2421  461 toggle private static ParameterizedType makeParameterizedType(Class<?> rawClass, Type[] typeParameters, Map<TypeVariable, Type> actualTypeMap) {
2422  461 int length = typeParameters.length;
2423  461 Type[] actualTypeArguments = new Type[length];
2424  931 for (int i = 0; i < length; i++) {
2425  470 actualTypeArguments[i] = getActualType(typeParameters[i], actualTypeMap);
2426    }
2427  461 return new ParameterizedTypeImpl(actualTypeArguments, null, rawClass);
2428    }
2429   
 
2430  474 toggle private static Type getActualType(Type typeParameter, Map<TypeVariable, Type> actualTypeMap) {
2431  474 if (typeParameter instanceof TypeVariable) {
2432  465 return actualTypeMap.get(typeParameter);
2433  9 } else if (typeParameter instanceof ParameterizedType) {
2434  2 return makeParameterizedType(getRawClass(typeParameter), ((ParameterizedType) typeParameter).getActualTypeArguments(), actualTypeMap);
2435  7 } else if (typeParameter instanceof GenericArrayType) {
2436  4 return new GenericArrayTypeImpl(getActualType(((GenericArrayType) typeParameter).getGenericComponentType(), actualTypeMap));
2437    }
2438  3 return typeParameter;
2439    }
2440   
 
2441  393 toggle private static Type getWildcardTypeUpperBounds(Type type) {
2442  393 if (type instanceof WildcardType) {
2443  13 WildcardType wildcardType = (WildcardType) type;
2444  13 Type[] upperBounds = wildcardType.getUpperBounds();
2445  13 return upperBounds.length > 0 ? upperBounds[0] : Object.class;
2446    }
2447  380 return type;
2448    }
2449   
 
2450  738 toggle public static Class<?> getCollectionItemClass(Type fieldType){
2451  738 if(fieldType instanceof ParameterizedType){
2452  722 Class<?> itemClass;
2453  722 Type actualTypeArgument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
2454  722 if(actualTypeArgument instanceof WildcardType){
2455  6 WildcardType wildcardType = (WildcardType) actualTypeArgument;
2456  6 Type[] upperBounds = wildcardType.getUpperBounds();
2457  6 if(upperBounds.length == 1){
2458  6 actualTypeArgument = upperBounds[0];
2459    }
2460    }
2461  722 if(actualTypeArgument instanceof Class){
2462  718 itemClass = (Class<?>) actualTypeArgument;
2463  718 if(!Modifier.isPublic(itemClass.getModifiers())){
2464  2 throw new JSONException("can not create ASMParser");
2465    }
2466    } else{
2467  4 throw new JSONException("can not create ASMParser");
2468    }
2469  716 return itemClass;
2470    }
2471  16 return Object.class;
2472    }
2473   
 
2474  9 toggle public static Type checkPrimitiveArray(GenericArrayType genericArrayType) {
2475  9 Type clz = genericArrayType;
2476  9 Type genericComponentType = genericArrayType.getGenericComponentType();
2477   
2478  9 String prefix = "[";
2479  9 while (genericComponentType instanceof GenericArrayType) {
2480  0 genericComponentType = ((GenericArrayType) genericComponentType)
2481    .getGenericComponentType();
2482  0 prefix += prefix;
2483    }
2484   
2485  9 if (genericComponentType instanceof Class<?>) {
2486  8 Class<?> ck = (Class<?>) genericComponentType;
2487  8 if (ck.isPrimitive()) {
2488  8 try {
2489  8 if (ck == boolean.class) {
2490  1 clz = Class.forName(prefix + "Z");
2491  7 } else if (ck == char.class) {
2492  1 clz = Class.forName(prefix + "C");
2493  6 } else if (ck == byte.class) {
2494  1 clz = Class.forName(prefix + "B");
2495  5 } else if (ck == short.class) {
2496  1 clz = Class.forName(prefix + "S");
2497  4 } else if (ck == int.class) {
2498  1 clz = Class.forName(prefix + "I");
2499  3 } else if (ck == long.class) {
2500  1 clz = Class.forName(prefix + "J");
2501  2 } else if (ck == float.class) {
2502  1 clz = Class.forName(prefix + "F");
2503  1 } else if (ck == double.class) {
2504  1 clz = Class.forName(prefix + "D");
2505    }
2506    } catch (ClassNotFoundException e) {
2507    }
2508    }
2509    }
2510   
2511  9 return clz;
2512    }
2513   
 
2514  170 toggle @SuppressWarnings({"rawtypes", "unchecked"})
2515    public static Collection createCollection(Type type) {
2516  170 Class<?> rawClass = getRawClass(type);
2517  170 Collection list;
2518  170 if(rawClass == AbstractCollection.class //
2519    || rawClass == Collection.class){
2520  18 list = new ArrayList();
2521  152 } else if(rawClass.isAssignableFrom(HashSet.class)){
2522  27 list = new HashSet();
2523  125 } else if(rawClass.isAssignableFrom(LinkedHashSet.class)){
2524  2 list = new LinkedHashSet();
2525  123 } else if(rawClass.isAssignableFrom(TreeSet.class)){
2526  17 list = new TreeSet();
2527  106 } else if(rawClass.isAssignableFrom(ArrayList.class)){
2528  85 list = new ArrayList();
2529  21 } else if(rawClass.isAssignableFrom(EnumSet.class)){
2530  2 Type itemType;
2531  2 if(type instanceof ParameterizedType){
2532  2 itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
2533    } else{
2534  0 itemType = Object.class;
2535    }
2536  2 list = EnumSet.noneOf((Class<Enum>) itemType);
2537  19 } else if(rawClass.isAssignableFrom(Queue.class)){
2538  1 list = new LinkedList();
2539    } else{
2540  18 try{
2541  18 list = (Collection) rawClass.newInstance();
2542    } catch(Exception e){
2543  5 throw new JSONException("create instance error, class " + rawClass.getName());
2544    }
2545    }
2546  165 return list;
2547    }
2548   
 
2549  2266 toggle public static Class<?> getRawClass(Type type){
2550  2266 if(type instanceof Class<?>){
2551  1202 return (Class<?>) type;
2552  1064 } else if(type instanceof ParameterizedType){
2553  1064 return getRawClass(((ParameterizedType) type).getRawType());
2554    } else{
2555  0 throw new JSONException("TODO");
2556    }
2557    }
2558   
 
2559  1635 toggle public static boolean isProxy(Class<?> clazz){
2560  1635 for(Class<?> item : clazz.getInterfaces()){
2561  159 String interfaceName = item.getName();
2562  159 if(interfaceName.equals("net.sf.cglib.proxy.Factory") //
2563    || interfaceName.equals("org.springframework.cglib.proxy.Factory")){
2564  1 return true;
2565    }
2566  158 if(interfaceName.equals("javassist.util.proxy.ProxyObject") //
2567    || interfaceName.equals("org.apache.ibatis.javassist.util.proxy.ProxyObject")
2568    ){
2569  1 return true;
2570    }
2571  157 if (interfaceName.equals("org.hibernate.proxy.HibernateProxy")) {
2572  0 return true;
2573    }
2574    }
2575  1633 return false;
2576    }
2577   
 
2578  15805 toggle public static boolean isTransient(Method method){
2579  15805 if(method == null){
2580  8725 return false;
2581    }
2582  7080 if(!transientClassInited){
2583  1 try{
2584  1 transientClass = (Class<? extends Annotation>) Class.forName("java.beans.Transient");
2585    } catch(Exception e){
2586    // skip
2587    } finally{
2588  1 transientClassInited = true;
2589    }
2590    }
2591  7080 if(transientClass != null){
2592  7080 Annotation annotation = TypeUtils.getAnnotation(method, transientClass);
2593  7081 return annotation != null;
2594    }
2595  0 return false;
2596    }
2597   
 
2598  9881 toggle public static boolean isAnnotationPresentOneToMany(Method method) {
2599  9881 if (method == null) {
2600  7217 return false;
2601    }
2602   
2603  2664 if (class_OneToMany == null && !class_OneToMany_error) {
2604  1 try {
2605  1 class_OneToMany = (Class<? extends Annotation>) Class.forName("javax.persistence.OneToMany");
2606    } catch (Throwable e) {
2607    // skip
2608  0 class_OneToMany_error = true;
2609    }
2610    }
2611  2663 return class_OneToMany != null && method.isAnnotationPresent(class_OneToMany);
2612   
2613    }
2614   
 
2615  9881 toggle public static boolean isAnnotationPresentManyToMany(Method method) {
2616  9881 if (method == null) {
2617  7217 return false;
2618    }
2619   
2620  2664 if (class_ManyToMany == null && !class_ManyToMany_error) {
2621  1 try {
2622  1 class_ManyToMany = (Class<? extends Annotation>) Class.forName("javax.persistence.ManyToMany");
2623    } catch (Throwable e) {
2624    // skip
2625  0 class_ManyToMany_error = true;
2626    }
2627    }
2628  2664 return class_ManyToMany != null && (method.isAnnotationPresent(class_OneToMany) || method.isAnnotationPresent(class_ManyToMany));
2629   
2630    }
2631   
 
2632  1 toggle public static boolean isHibernateInitialized(Object object){
2633  1 if(object == null){
2634  0 return false;
2635    }
2636  1 if(method_HibernateIsInitialized == null && !method_HibernateIsInitialized_error){
2637  1 try{
2638  1 Class<?> class_Hibernate = Class.forName("org.hibernate.Hibernate");
2639  1 method_HibernateIsInitialized = class_Hibernate.getMethod("isInitialized", Object.class);
2640    } catch(Throwable e){
2641    // skip
2642  0 method_HibernateIsInitialized_error = true;
2643    }
2644    }
2645  1 if(method_HibernateIsInitialized != null){
2646  1 try{
2647  1 Boolean initialized = (Boolean) method_HibernateIsInitialized.invoke(null, object);
2648  1 return initialized.booleanValue();
2649    } catch(Throwable e){
2650    // skip
2651    }
2652    }
2653  0 return true;
2654    }
2655   
 
2656  5000032 toggle public static double parseDouble(String str) {
2657  5000032 final int len = str.length();
2658  5000032 if (len > 10) {
2659  2329798 return Double.parseDouble(str);
2660    }
2661   
2662  2670234 boolean negative = false;
2663   
2664  2670234 long longValue = 0;
2665  2670234 int scale = 0;
2666  27535268 for (int i = 0; i < len; ++i) {
2667  24865074 char ch = str.charAt(i);
2668  24865074 if (ch == '-' && i == 0) {
2669  233229 negative = true;
2670  233229 continue;
2671    }
2672   
2673  24631845 if (ch == '.') {
2674  937167 if (scale != 0) {
2675  0 return Double.parseDouble(str);
2676    }
2677  937167 scale = len - i - 1;
2678  937167 continue;
2679    }
2680   
2681  23694678 if (ch >= '0' && ch <= '9') {
2682  23694638 int digit = ch - '0';
2683  23694638 longValue = longValue * 10 + digit;
2684    } else {
2685  40 return Double.parseDouble(str);
2686    }
2687    }
2688   
2689  2670194 if (negative) {
2690  233229 longValue = -longValue;
2691    }
2692   
2693  2670194 switch (scale) {
2694  1733067 case 0:
2695  1733067 return (double) longValue;
2696  12 case 1:
2697  12 return ((double) longValue) / 10;
2698  3 case 2:
2699  3 return ((double) longValue) / 100;
2700  31 case 3:
2701  31 return ((double) longValue) / 1000;
2702  367 case 4:
2703  367 return ((double) longValue) / 10000;
2704  3554 case 5:
2705  3554 return ((double) longValue) / 100000;
2706  35596 case 6:
2707  35596 return ((double) longValue) / 1000000;
2708  357756 case 7:
2709  357756 return ((double) longValue) / 10000000;
2710  539808 case 8:
2711  539808 return ((double) longValue) / 100000000;
2712  0 case 9:
2713  0 return ((double) longValue) / 1000000000;
2714    }
2715   
2716  0 return Double.parseDouble(str);
2717    }
2718   
 
2719  4000032 toggle public static float parseFloat(String str) {
2720  4000032 final int len = str.length();
2721  4000032 if (len >= 10) {
2722  2347056 return Float.parseFloat(str);
2723    }
2724   
2725  1652976 boolean negative = false;
2726   
2727  1652976 long longValue = 0;
2728  1652976 int scale = 0;
2729  16346149 for (int i = 0; i < len; ++i) {
2730  14693176 char ch = str.charAt(i);
2731  14693176 if (ch == '-' && i == 0) {
2732  23453 negative = true;
2733  23453 continue;
2734    }
2735   
2736  14669723 if (ch == '.') {
2737  397411 if (scale != 0) {
2738  0 return Float.parseFloat(str);
2739    }
2740  397411 scale = len - i - 1;
2741  397411 continue;
2742    }
2743   
2744  14272312 if (ch >= '0' && ch <= '9') {
2745  14272309 int digit = ch - '0';
2746  14272309 longValue = longValue * 10 + digit;
2747    } else {
2748  3 return Float.parseFloat(str);
2749    }
2750    }
2751   
2752  1652973 if (negative) {
2753  23453 longValue = -longValue;
2754    }
2755   
2756  1652973 switch (scale) {
2757  1255565 case 0:
2758  1255565 return (float) longValue;
2759  10 case 1:
2760  10 return ((float) longValue) / 10;
2761  4 case 2:
2762  4 return ((float) longValue) / 100;
2763  33 case 3:
2764  33 return ((float) longValue) / 1000;
2765  374 case 4:
2766  374 return ((float) longValue) / 10000;
2767  3545 case 5:
2768  3545 return ((float) longValue) / 100000;
2769  35790 case 6:
2770  35790 return ((float) longValue) / 1000000;
2771  357652 case 7:
2772  357652 return ((float) longValue) / 10000000;
2773  0 case 8:
2774  0 return ((float) longValue) / 100000000;
2775  0 case 9:
2776  0 return ((float) longValue) / 1000000000;
2777    }
2778   
2779  0 return Float.parseFloat(str);
2780    }
2781   
 
2782  447 toggle public static long fnv1a_64_lower(String key){
2783  447 long hashCode = 0xcbf29ce484222325L;
2784  3235 for(int i = 0; i < key.length(); ++i){
2785  2788 char ch = key.charAt(i);
2786  2788 if(ch == '_' || ch == '-'){
2787  44 continue;
2788    }
2789  2744 if(ch >= 'A' && ch <= 'Z'){
2790  183 ch = (char) (ch + 32);
2791    }
2792  2744 hashCode ^= ch;
2793  2744 hashCode *= 0x100000001b3L;
2794    }
2795  447 return hashCode;
2796    }
2797   
 
2798  4307 toggle public static long fnv1a_64(String key){
2799  4307 long hashCode = 0xcbf29ce484222325L;
2800  98349 for(int i = 0; i < key.length(); ++i){
2801  94042 char ch = key.charAt(i);
2802  94042 hashCode ^= ch;
2803  94044 hashCode *= 0x100000001b3L;
2804    }
2805  4307 return hashCode;
2806    }
2807   
 
2808  4327 toggle public static boolean isKotlin(Class clazz) {
2809  4327 if (kotlin_metadata == null && !kotlin_metadata_error) {
2810  1 try {
2811  1 kotlin_metadata = Class.forName("kotlin.Metadata");
2812    } catch (Throwable e) {
2813  0 kotlin_metadata_error = true;
2814    }
2815    }
2816  4327 return kotlin_metadata != null && clazz.isAnnotationPresent(kotlin_metadata);
2817    }
2818   
 
2819  20 toggle public static Constructor getKoltinConstructor(Constructor[] constructors){
2820  20 return getKoltinConstructor(constructors, null);
2821    }
2822   
 
2823  39 toggle public static Constructor getKoltinConstructor(Constructor[] constructors, String[] paramNames){
2824  39 Constructor creatorConstructor = null;
2825  39 for(Constructor<?> constructor : constructors){
2826  67 Class<?>[] parameterTypes = constructor.getParameterTypes();
2827  67 if (paramNames != null && parameterTypes.length != paramNames.length) {
2828  13 continue;
2829    }
2830   
2831  54 if(parameterTypes.length > 0 && parameterTypes[parameterTypes.length - 1].getName().equals("kotlin.jvm.internal.DefaultConstructorMarker")){
2832  6 continue;
2833    }
2834  48 if(creatorConstructor != null && creatorConstructor.getParameterTypes().length >= parameterTypes.length){
2835  5 continue;
2836    }
2837  43 creatorConstructor = constructor;
2838    }
2839  39 return creatorConstructor;
2840    }
2841   
 
2842  66 toggle public static String[] getKoltinConstructorParameters(Class clazz){
2843  66 if(kotlin_kclass_constructor == null && !kotlin_class_klass_error){
2844  1 try{
2845  1 Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
2846  1 kotlin_kclass_constructor = class_kotlin_kclass.getConstructor(Class.class);
2847    } catch(Throwable e){
2848  0 kotlin_class_klass_error = true;
2849    }
2850    }
2851  66 if (kotlin_kclass_constructor == null){
2852  0 return null;
2853    }
2854   
2855  66 if (kotlin_kclass_getConstructors == null && !kotlin_class_klass_error) {
2856  1 try{
2857  1 Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
2858  1 kotlin_kclass_getConstructors = class_kotlin_kclass.getMethod("getConstructors");
2859    } catch(Throwable e){
2860  0 kotlin_class_klass_error = true;
2861    }
2862    }
2863   
2864  66 if (kotlin_kfunction_getParameters == null && !kotlin_class_klass_error) {
2865  1 try{
2866  1 Class class_kotlin_kfunction = Class.forName("kotlin.reflect.KFunction");
2867  1 kotlin_kfunction_getParameters = class_kotlin_kfunction.getMethod("getParameters");
2868    } catch(Throwable e){
2869  0 kotlin_class_klass_error = true;
2870    }
2871    }
2872   
2873  66 if (kotlin_kparameter_getName == null && !kotlin_class_klass_error) {
2874  1 try{
2875  1 Class class_kotlinn_kparameter = Class.forName("kotlin.reflect.KParameter");
2876  1 kotlin_kparameter_getName = class_kotlinn_kparameter.getMethod("getName");
2877    } catch(Throwable e){
2878  0 kotlin_class_klass_error = true;
2879    }
2880    }
2881   
2882  66 if (kotlin_error){
2883  0 return null;
2884    }
2885   
2886  66 try{
2887  66 Object constructor = null;
2888  66 Object kclassImpl = kotlin_kclass_constructor.newInstance(clazz);
2889  66 Iterable it = (Iterable) kotlin_kclass_getConstructors.invoke(kclassImpl);
2890  141 for(Iterator iterator = it.iterator(); iterator.hasNext(); iterator.hasNext()){
2891  75 Object item = iterator.next();
2892  75 List parameters = (List) kotlin_kfunction_getParameters.invoke(item);
2893  75 if (constructor != null && parameters.size() == 0) {
2894  6 continue;
2895    }
2896  69 constructor = item;
2897    }
2898  66 List parameters = (List) kotlin_kfunction_getParameters.invoke(constructor);
2899  66 String[] names = new String[parameters.size()];
2900  239 for(int i = 0; i < parameters.size(); i++){
2901  173 Object param = parameters.get(i);
2902  173 names[i] = (String) kotlin_kparameter_getName.invoke(param);
2903    }
2904  66 return names;
2905    } catch(Throwable e){
2906  0 e.printStackTrace();
2907  0 kotlin_error = true;
2908    }
2909  0 return null;
2910    }
2911   
 
2912  168 toggle private static boolean isKotlinIgnore(Class clazz, String methodName) {
2913  168 if (kotlinIgnores == null && !kotlinIgnores_error) {
2914  1 try {
2915  1 Map<Class, String[]> map = new HashMap<Class, String[]>();
2916  1 Class charRangeClass = Class.forName("kotlin.ranges.CharRange");
2917  1 map.put(charRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2918  1 Class intRangeClass = Class.forName("kotlin.ranges.IntRange");
2919  1 map.put(intRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2920  1 Class longRangeClass = Class.forName("kotlin.ranges.LongRange");
2921  1 map.put(longRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2922  1 Class floatRangeClass = Class.forName("kotlin.ranges.ClosedFloatRange");
2923  1 map.put(floatRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2924  1 Class doubleRangeClass = Class.forName("kotlin.ranges.ClosedDoubleRange");
2925  1 map.put(doubleRangeClass, new String[]{"getEndInclusive", "isEmpty"});
2926  1 kotlinIgnores = map;
2927    } catch (Throwable error) {
2928  0 kotlinIgnores_error = true;
2929    }
2930    }
2931  168 if (kotlinIgnores == null) {
2932  0 return false;
2933    }
2934  168 String[] ignores = kotlinIgnores.get(clazz);
2935  168 return ignores != null && Arrays.binarySearch(ignores, methodName) >= 0;
2936    }
2937   
 
2938  17176 toggle public static <A extends Annotation> A getAnnotation(Class<?> targetClass, Class<A> annotationClass){
2939  17177 A targetAnnotation = targetClass.getAnnotation(annotationClass);
2940   
2941  17179 Class<?> mixInClass = null;
2942  17177 Type type = JSON.getMixInAnnotations(targetClass);
2943  17179 if (type instanceof Class<?>) {
2944  62 mixInClass = (Class<?>) type;
2945    }
2946   
2947  17179 if(mixInClass != null) {
2948  62 A mixInAnnotation = mixInClass.getAnnotation(annotationClass);
2949  62 if(mixInAnnotation == null && mixInClass.getAnnotations().length > 0){
2950  0 for(Annotation annotation : mixInClass.getAnnotations()){
2951  0 mixInAnnotation = annotation.annotationType().getAnnotation(annotationClass);
2952  0 if(mixInAnnotation != null){
2953  0 break;
2954    }
2955    }
2956    }
2957  62 if (mixInAnnotation != null) {
2958  28 return mixInAnnotation;
2959    }
2960    }
2961   
2962  17149 if(targetAnnotation == null && targetClass.getAnnotations().length > 0){
2963  279 for(Annotation annotation : targetClass.getAnnotations()){
2964  293 targetAnnotation = annotation.annotationType().getAnnotation(annotationClass);
2965  293 if(targetAnnotation != null){
2966  0 break;
2967    }
2968    }
2969    }
2970  17150 return targetAnnotation;
2971    }
2972   
 
2973  16593 toggle public static <A extends Annotation> A getAnnotation(Field field, Class<A> annotationClass){
2974  16592 A targetAnnotation = field.getAnnotation(annotationClass);
2975   
2976  16593 Class<?> clazz = field.getDeclaringClass();
2977  16593 A mixInAnnotation;
2978  16593 Class<?> mixInClass = null;
2979  16593 Type type = JSON.getMixInAnnotations(clazz);
2980  16593 if (type instanceof Class<?>) {
2981  29 mixInClass = (Class<?>) type;
2982    }
2983   
2984  16593 if (mixInClass != null) {
2985  29 Field mixInField = null;
2986  29 String fieldName = field.getName();
2987    // 递归从MixIn类的父类中查找注解(如果有父类的话)
2988  44 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
2989    currClass = currClass.getSuperclass()) {
2990  35 try {
2991  35 mixInField = currClass.getDeclaredField(fieldName);
2992  20 break;
2993    } catch (NoSuchFieldException e) {
2994    // skip
2995    }
2996    }
2997  29 if (mixInField == null) {
2998  9 return targetAnnotation;
2999    }
3000  20 mixInAnnotation = mixInField.getAnnotation(annotationClass);
3001  20 if (mixInAnnotation != null) {
3002  20 return mixInAnnotation;
3003    }
3004    }
3005  16564 return targetAnnotation;
3006    }
3007   
 
3008  19743 toggle public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationClass){
3009  19743 A targetAnnotation = method.getAnnotation(annotationClass);
3010   
3011  19745 Class<?> clazz = method.getDeclaringClass();
3012  19745 A mixInAnnotation;
3013  19745 Class<?> mixInClass = null;
3014  19745 Type type = JSON.getMixInAnnotations(clazz);
3015  19745 if (type instanceof Class<?>) {
3016  35 mixInClass = (Class<?>) type;
3017    }
3018   
3019  19744 if (mixInClass != null) {
3020  35 Method mixInMethod = null;
3021  35 String methodName = method.getName();
3022  35 Class<?>[] parameterTypes = method.getParameterTypes();
3023    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3024  62 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3025    currClass = currClass.getSuperclass()) {
3026  37 try {
3027  37 mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes);
3028  10 break;
3029    } catch (NoSuchMethodException e) {
3030    // skip
3031    }
3032    }
3033  35 if (mixInMethod == null) {
3034  25 return targetAnnotation;
3035    }
3036  10 mixInAnnotation = mixInMethod.getAnnotation(annotationClass);
3037  10 if (mixInAnnotation != null) {
3038  4 return mixInAnnotation;
3039    }
3040    }
3041  19715 return targetAnnotation;
3042    }
3043   
 
3044  22 toggle public static Annotation[][] getParameterAnnotations(Method method){
3045  22 Annotation[][] targetAnnotations = method.getParameterAnnotations();
3046   
3047  22 Class<?> clazz = method.getDeclaringClass();
3048  22 Annotation[][] mixInAnnotations;
3049  22 Class<?> mixInClass = null;
3050  22 Type type = JSON.getMixInAnnotations(clazz);
3051  22 if (type instanceof Class<?>) {
3052  0 mixInClass = (Class<?>) type;
3053    }
3054   
3055  22 if (mixInClass != null) {
3056  0 Method mixInMethod = null;
3057  0 String methodName = method.getName();
3058  0 Class<?>[] parameterTypes = method.getParameterTypes();
3059    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3060  0 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3061    currClass = currClass.getSuperclass()) {
3062  0 try {
3063  0 mixInMethod = currClass.getDeclaredMethod(methodName, parameterTypes);
3064  0 break;
3065    } catch (NoSuchMethodException e) {
3066  0 continue;
3067    }
3068    }
3069  0 if (mixInMethod == null) {
3070  0 return targetAnnotations;
3071    }
3072  0 mixInAnnotations = mixInMethod.getParameterAnnotations();
3073  0 if (mixInAnnotations != null) {
3074  0 return mixInAnnotations;
3075    }
3076    }
3077  22 return targetAnnotations;
3078    }
3079   
 
3080  403 toggle public static Annotation[][] getParameterAnnotations(Constructor constructor){
3081  403 Annotation[][] targetAnnotations = constructor.getParameterAnnotations();
3082   
3083  403 Class<?> clazz = constructor.getDeclaringClass();
3084  403 Annotation[][] mixInAnnotations;
3085  403 Class<?> mixInClass = null;
3086  403 Type type = JSON.getMixInAnnotations(clazz);
3087  403 if (type instanceof Class<?>) {
3088  3 mixInClass = (Class<?>) type;
3089    }
3090   
3091  403 if (mixInClass != null) {
3092  3 Constructor mixInConstructor = null;
3093  3 Class<?>[] parameterTypes = constructor.getParameterTypes();
3094    // 构建参数列表,因为内部类的构造函数需要传入外部类的引用
3095  3 List<Class<?>> enclosingClasses = new ArrayList<Class<?>>(2);
3096  6 for (Class<?> enclosingClass = mixInClass.getEnclosingClass(); enclosingClass != null; enclosingClass = enclosingClass.getEnclosingClass()) {
3097  3 enclosingClasses.add(enclosingClass);
3098    }
3099  3 int level = enclosingClasses.size();
3100    // 递归从MixIn类的父类中查找注解(如果有父类的话)
3101  3 for (Class<?> currClass = mixInClass; currClass != null && currClass != Object.class;
3102    currClass = currClass.getSuperclass()) {
3103  3 try {
3104  3 if (level != 0) {
3105  3 Class<?>[] outerClassAndParameterTypes = new Class[level + parameterTypes.length];
3106  3 System.arraycopy(parameterTypes, 0, outerClassAndParameterTypes, level, parameterTypes.length);
3107  6 for (int i = level; i > 0 ; i--) {
3108  3 outerClassAndParameterTypes[i - 1] = enclosingClasses.get(i - 1);
3109    }
3110  3 mixInConstructor = mixInClass.getDeclaredConstructor(outerClassAndParameterTypes);
3111    } else {
3112  0 mixInConstructor = mixInClass.getDeclaredConstructor(parameterTypes);
3113    }
3114  3 break;
3115    } catch (NoSuchMethodException e) {
3116  0 level--;
3117    }
3118    }
3119  3 if (mixInConstructor == null) {
3120  0 return targetAnnotations;
3121    }
3122  3 mixInAnnotations = mixInConstructor.getParameterAnnotations();
3123  3 if (mixInAnnotations != null) {
3124  3 return mixInAnnotations;
3125    }
3126    }
3127  400 return targetAnnotations;
3128    }
3129   
 
3130  15 toggle public static boolean isJacksonCreator(Method method) {
3131  15 if (method == null) {
3132  0 return false;
3133    }
3134   
3135  15 if (class_JacksonCreator == null && !class_JacksonCreator_error) {
3136  1 try {
3137  1 class_JacksonCreator = (Class<? extends Annotation>) Class.forName("com.fasterxml.jackson.annotation.JsonCreator");
3138    } catch (Throwable e) {
3139    // skip
3140  0 class_JacksonCreator_error = true;
3141    }
3142    }
3143  15 return class_JacksonCreator != null && method.isAnnotationPresent(class_JacksonCreator);
3144    }
3145    }